< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.SharedState.SharedState
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/SharedState/SharedState.cs
Tag: Kestrun/Kestrun@0d738bf294e6281b936d031e1979d928007495ff
Line coverage
100%
Covered lines: 41
Uncovered lines: 0
Coverable lines: 41
Total lines: 153
Line coverage: 100%
Branch coverage
100%
Covered branches: 18
Total branches: 18
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/14/2025 - 12:29:34 Line coverage: 70.7% (29/41) Branch coverage: 66.6% (12/18) Total lines: 153 Tag: Kestrun/Kestrun@5e12b09a6838e68e704cd3dc975331b9e680a62612/15/2025 - 18:44:50 Line coverage: 100% (41/41) Branch coverage: 100% (18/18) Total lines: 153 Tag: Kestrun/Kestrun@6b9e56ea2de904fc3597033ef0f9bc7839d5d618 11/14/2025 - 12:29:34 Line coverage: 70.7% (29/41) Branch coverage: 66.6% (12/18) Total lines: 153 Tag: Kestrun/Kestrun@5e12b09a6838e68e704cd3dc975331b9e680a62612/15/2025 - 18:44:50 Line coverage: 100% (41/41) Branch coverage: 100% (18/18) Total lines: 153 Tag: Kestrun/Kestrun@6b9e56ea2de904fc3597033ef0f9bc7839d5d618

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor(...)100%22100%
Set(...)100%11100%
Contains(...)100%11100%
TryGet(...)100%44100%
Get(...)100%22100%
Snapshot()100%11100%
KeySnapshot()100%11100%
Clear()100%11100%
get_Count()100%11100%
get_Keys()100%11100%
get_Values()100%11100%
Remove(...)100%11100%
ValidateName(...)100%44100%
ValidateValue(...)100%66100%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/SharedState/SharedState.cs

#LineLine coverage
 1using System.Collections.Concurrent;
 2using System.Text.RegularExpressions;
 3
 4namespace Kestrun.SharedState;
 5
 6/// <summary>
 7/// Thread‑safe, case‑insensitive global key/value store for reference‑type objects.
 8/// </summary>
 9public partial class SharedState
 10{
 11    // ── configuration ───────────────────────────────────────────────
 112    private static readonly Regex _validName =
 113        MyRegex();
 14
 15    // StringComparer.OrdinalIgnoreCase ⇒ 100 % case‑insensitive keys
 16    private readonly ConcurrentDictionary<string, object?> _store;
 17
 18    /// <summary>
 19    /// Initializes a new instance of the <see cref="SharedState"/> class.
 20    /// </summary>
 21    /// <param name="ordinalIgnoreCase">If <c>true</c>, keys are compared in a case-insensitive manner; otherwise, case-
 51822    public SharedState(bool ordinalIgnoreCase = true)
 23    {
 51824        if (ordinalIgnoreCase)
 25        {
 51726            _store = new(StringComparer.OrdinalIgnoreCase);
 51727            return;
 28        }
 29        else
 30        {
 131            _store = new(StringComparer.Ordinal);
 32        }
 133    }
 34
 35    // ── public API ──────────────────────────────────────────────────
 36    /// <summary>
 37    /// Add or overwrite a value (reference‑types only).
 38    /// </summary>
 39    /// <param name="name">The name of the variable to set.</param>
 40    /// <param name="value">The value to set. Must be a reference type unless <paramref name="allowsValueType"/> is <c>t
 41    /// <param name="allowsValueType">If <c>true</c>, allows setting value types; otherwise, only reference types are al
 42    /// <returns><c>true</c> if the value was set successfully.</returns>
 43    public bool Set(string name, object? value, bool allowsValueType = false)
 44    {
 56245        ValidateName(name);
 54746        ValidateValue(name, value, allowsValueType);
 53947        _store[name] = value;
 53948        return true;
 49    }
 50
 51    /// <summary>
 52    /// Checks if a variable with the specified name exists in the shared state.
 53    /// </summary>
 54    /// <param name="name">The name of the variable to check.</param>
 55    /// <returns> <c>true</c> if the variable exists; otherwise, <c>false</c>.</returns>
 3356    public bool Contains(string name) => _store.ContainsKey(name);
 57
 58    /// <summary>
 59    /// Strongly‑typed fetch. Returns <c>false</c> if the key is missing
 60    /// or the stored value can’t be cast to <typeparamref name="T"/>.
 61    /// </summary>
 62    public bool TryGet<T>(string name, out T? value)
 63    {
 1664        if (_store.TryGetValue(name, out var raw) && raw is T cast)
 65        {
 1066            value = cast;
 1067            return true;
 68        }
 669        value = default;
 670        return false;
 71    }
 72
 73    /// <summary>Untyped fetch; <c>null</c> if absent.</summary>
 74    public object? Get(string name) =>
 6175        _store.TryGetValue(name, out var val) ? val : null;
 76
 77    /// <summary>Snapshot of *all* current variables (shallow copy).</summary>
 78    public IReadOnlyDictionary<string, object?> Snapshot() =>
 27679        _store.ToDictionary(kvp => kvp.Key, kvp => kvp.Value,
 24880                            StringComparer.OrdinalIgnoreCase);
 81
 82    /// <summary>Snapshot of keys only—handy for quick listings.</summary>
 83    public IReadOnlyCollection<string> KeySnapshot() =>
 584        [.. _store.Keys];
 85
 86    /// <summary>
 87    /// Clears all entries in the shared state.
 88    /// </summary>
 89    public void Clear() =>
 10990        _store.Clear();
 91
 92    /// <summary>
 93    /// Gets the number of key/value pairs in the shared state.
 94    /// </summary>
 95    public int Count =>
 2796        _store.Count;
 97    /// <summary>
 98    /// Gets an enumerable collection of all keys in the shared state.
 99    /// </summary>
 100    public IEnumerable<string> Keys =>
 3101        _store.Keys;
 102    /// <summary>
 103    /// Gets an enumerable collection of all values in the shared state.
 104    /// </summary>
 105    public IEnumerable<object?> Values =>
 3106        _store.Values;
 107
 108    /// <summary>
 109    /// Attempts to remove the value with the specified name from the shared state.
 110    /// </summary>
 111    /// <param name="name">The name of the variable to remove.</param>
 112    /// <returns><c>true</c> if the variable was successfully removed; otherwise, <c>false</c>.</returns>
 113    public bool Remove(string name) =>
 209114            _store.Remove(name, out _);
 115
 116    // ── helpers ────────────────────────────────────────────────────
 117    private static void ValidateName(string name)
 118    {
 562119        if (string.IsNullOrWhiteSpace(name) || !_validName.IsMatch(name))
 120        {
 15121            throw new ArgumentException(
 15122                $"'{name}' is not a valid identifier for C# / PowerShell.",
 15123                nameof(name));
 124        }
 547125    }
 126
 127    /// <summary>
 128    /// Validates the value to be stored in the shared state.
 129    /// </summary>
 130    /// <param name="name">The name of the variable.</param>
 131    /// <param name="value">The value to validate.</param>
 132    /// <param name="allowsValueType">Indicates whether value types are allowed.</param>
 133    /// <exception cref="ArgumentException">Thrown if the value is a value type and value types are not allowed.</except
 134    private static void ValidateValue(string name, object? value, bool allowsValueType = false)
 135    {
 547136        if (value is null)
 137        {
 5138            return;                       // null is allowed
 139        }
 140
 542141        var t = value.GetType();
 542142        if (t.IsValueType && !allowsValueType)
 143        {
 8144            throw new ArgumentException(
 8145                $"Cannot define global variable '{name}' of value type '{t.FullName}'. " +
 8146                "Only reference types are allowed.",
 8147                nameof(value));
 148        }
 534149    }
 150
 151    [GeneratedRegex(@"^[A-Za-z_][A-Za-z0-9_]*$", RegexOptions.CultureInvariant)]
 152    private static partial Regex MyRegex();
 153}