< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.Utilities.Yaml.IDictionaryTypeConverter
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Utilities/Yaml/IDictionaryTypeConverter.cs
Tag: Kestrun/Kestrun@2d87023b37eb91155071c91dd3d6a2eeb3004705
Line coverage
63%
Covered lines: 24
Uncovered lines: 14
Coverable lines: 38
Total lines: 114
Line coverage: 63.1%
Branch coverage
58%
Covered branches: 14
Total branches: 24
Branch coverage: 58.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 10/13/2025 - 16:52:37 Line coverage: 63.1% (24/38) Branch coverage: 58.3% (14/24) Total lines: 114 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e 10/13/2025 - 16:52:37 Line coverage: 63.1% (24/38) Branch coverage: 58.3% (14/24) Total lines: 114 Tag: Kestrun/Kestrun@10d476bee71c71ad215bb8ab59f219887b5b4a5e

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Accepts(...)100%11100%
ReadYaml(...)0%620%
WriteYaml(...)63.63%482262.5%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Utilities/Yaml/IDictionaryTypeConverter.cs

#LineLine coverage
 1using System.Collections;
 2using System.Management.Automation;
 3using YamlDotNet.Core;
 4using YamlDotNet.Core.Events;
 5using YamlDotNet.Serialization;
 6
 7namespace Kestrun.Utilities.Yaml;
 8
 9/// <summary>
 10/// YAML type converter for IDictionary types
 11/// </summary>
 12/// <remarks>
 13/// Constructor
 14/// </remarks>
 15/// <param name="omitNullValues">If true, null values will be omitted from the output</param>
 16/// <param name="useFlowStyle">If true, the mapping will be emitted in flow style</param>
 2117public class IDictionaryTypeConverter(bool omitNullValues = false, bool useFlowStyle = false) : IYamlTypeConverter
 18{
 2119    private readonly bool omitNullValues = omitNullValues;
 2120    private readonly bool useFlowStyle = useFlowStyle;
 21
 22    /// <summary>
 23    /// Check if the type is IDictionary
 24    /// </summary>
 25    /// <param name="type">The type to check</param>
 26    /// <returns>true if the type is IDictionary; otherwise, false.</returns>
 11127    public bool Accepts(Type type) => typeof(IDictionary).IsAssignableFrom(type);
 28
 29    /// <summary>
 30    /// Read an IDictionary from YAML
 31    /// </summary>
 32    /// <param name="parser">The YAML parser</param>
 33    /// <param name="type">The type of the object to deserialize</param>
 34    /// <param name="rootDeserializer">The root deserializer</param>
 35    /// <returns>The deserialized object</returns>
 36    public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer)
 37    {
 038        var deserializedObject = rootDeserializer(typeof(IDictionary<string, object>)) as IDictionary;
 39        // Ensure a non-null IDictionary is returned to satisfy nullable reference expectations.
 040        return deserializedObject ?? new Hashtable();
 41    }
 42
 43    /// <summary>
 44    /// Write an IDictionary to YAML
 45    /// </summary>
 46    /// <param name="emitter">The YAML emitter</param>
 47    /// <param name="value">The IDictionary to serialize</param>
 48    /// <param name="type">The type of the object to serialize</param>
 49    /// <param name="serializer">The object serializer</param>
 50    public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer)
 51    {
 352        if (value == null)
 53        {
 54            // Emit explicit YAML null for a null dictionary value
 055            emitter.Emit(new Scalar(AnchorName.Empty, "tag:yaml.org,2002:null", "", ScalarStyle.Plain, true, false));
 056            return;
 57        }
 58
 359        var hObj = (IDictionary)value;
 360        var mappingStyle = useFlowStyle ? MappingStyle.Flow : MappingStyle.Block;
 61
 362        emitter.Emit(new MappingStart(AnchorName.Empty, TagName.Empty, true, mappingStyle));
 2063        foreach (DictionaryEntry entry in hObj)
 64        {
 765            if (entry.Value == null)
 66            {
 367                if (omitNullValues)
 68                {
 69                    continue;
 70                }
 71                // Emit a blank plain scalar (no quotes) to represent YAML null for dictionary entries (implicit null, n
 272                serializer(entry.Key, entry.Key.GetType());
 73                // Must set at least one implicit flag to true when tag is empty; plain implicit=true allows empty scala
 274                emitter.Emit(new Scalar(AnchorName.Empty, TagName.Empty, string.Empty, ScalarStyle.Plain, true, false));
 275                continue;
 76            }
 477            serializer(entry.Key, entry.Key.GetType());
 478            var objType = entry.Value.GetType();
 479            var val = entry.Value;
 80            // If empty string, emit explicitly as double-quoted to satisfy tests distinguishing from null blank.
 481            if (val is string s && s.Length == 0)
 82            {
 283                emitter.Emit(new Scalar(AnchorName.Empty, TagName.Empty, string.Empty, ScalarStyle.DoubleQuoted, true, f
 284                continue;
 85            }
 286            if (entry.Value is PSObject nestedObj)
 87            {
 088                if (nestedObj.BaseObject == null)
 89                {
 090                    if (omitNullValues)
 91                    {
 92                        continue;
 93                    }
 94                    // Emit a blank plain scalar (no quotes) to represent YAML null for dictionary entries (implicit nul
 095                    serializer(entry.Key, entry.Key.GetType());
 096                    emitter.Emit(new Scalar(AnchorName.Empty, TagName.Empty, string.Empty, ScalarStyle.Plain, true, fals
 097                    continue;
 98                }
 099                var nestedType = nestedObj.BaseObject.GetType();
 0100                if (nestedType != typeof(PSCustomObject))
 101                {
 0102                    objType = nestedObj.BaseObject.GetType();
 0103                    val = nestedObj.BaseObject;
 104                }
 0105                serializer(val, objType);
 106            }
 107            else
 108            {
 2109                serializer(entry.Value, entry.Value.GetType());
 110            }
 111        }
 3112        emitter.Emit(new MappingEnd());
 3113    }
 114}