< Summary - Combined Code Coverage

Information
Class: NLightning.Bolt11.Models.TaggedFieldList
Assembly: NLightning.Bolt11
File(s): /home/runner/work/nlightning/nlightning/src/NLightning.Bolt11/Models/TaggedFieldList.cs
Tag: 30_15166811759
Line coverage
97%
Covered lines: 72
Uncovered lines: 2
Coverable lines: 74
Total lines: 246
Line coverage: 97.2%
Branch coverage
100%
Covered branches: 40
Total branches: 40
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
Add(...)100%1414100%
AddRange(...)100%22100%
Remove(...)100%22100%
RemoveAt(...)100%11100%
RemoveAll(...)100%22100%
RemoveRange(...)100%11100%
TryGet(...)100%22100%
TryGetAll(...)100%22100%
FromBitReader(...)100%10.161088.24%
WriteToBitWriter(...)100%22100%
CalculateSizeInBits()100%11100%
Get(...)100%11100%
GetAll(...)100%22100%
OnChanged()100%22100%

File(s)

/home/runner/work/nlightning/nlightning/src/NLightning.Bolt11/Models/TaggedFieldList.cs

#LineLine coverage
 1using System.Diagnostics;
 2
 3namespace NLightning.Bolt11.Models;
 4
 5using Common.Utils;
 6using Domain.ValueObjects;
 7using Enums;
 8using Factories;
 9using Interfaces;
 10
 11/// <summary>
 12/// A list of tagged fields
 13/// </summary>
 14internal class TaggedFieldList : List<ITaggedField>
 15{
 39616    private bool _shouldInvokeChangedEvent = true;
 17    public event EventHandler? Changed;
 18
 19    /// <summary>
 20    /// Add a tagged field to the list
 21    /// </summary>
 22    /// <param name="taggedField">The tagged field to add</param>
 23    /// <exception cref="ArgumentException">If the tagged field is not unique</exception>
 24    internal new void Add(ITaggedField taggedField)
 25    {
 26        // Check for uniqueness
 254027        if (this.Any(x => x.Type.Equals(taggedField.Type)) && taggedField.Type != TaggedFieldTypes.FALLBACK_ADDRESS)
 28        {
 429            throw new ArgumentException($"TaggedFieldDictionary already contains a tagged field of type {taggedField.Typ
 30        }
 31
 89232        switch (taggedField.Type)
 33        {
 25234            case TaggedFieldTypes.DESCRIPTION when this.Any(x => x.Type.Equals(TaggedFieldTypes.DESCRIPTION_HASH)):
 435                throw new ArgumentException($"TaggedFieldDictionary already contains a tagged field of type {taggedField
 13236            case TaggedFieldTypes.DESCRIPTION_HASH when this.Any(x => x.Type.Equals(TaggedFieldTypes.DESCRIPTION)):
 437                throw new ArgumentException($"TaggedFieldDictionary already contains a tagged field of type {taggedField
 38            default:
 88439                base.Add(taggedField);
 88440                if (_shouldInvokeChangedEvent)
 41                {
 84842                    OnChanged();
 43                }
 44                break;
 45        }
 88446    }
 47
 48    /// <summary>
 49    /// Add a range of tagged fields to the list
 50    /// </summary>
 51    /// <param name="taggedFields">The tagged fields to add</param>
 52    internal new void AddRange(IEnumerable<ITaggedField> taggedFields)
 53    {
 2854        _shouldInvokeChangedEvent = false;
 55
 12856        foreach (var taggedField in taggedFields)
 57        {
 3658            Add(taggedField);
 59        }
 60
 2861        _shouldInvokeChangedEvent = true;
 2862        OnChanged();
 2863    }
 64
 65    internal new bool Remove(ITaggedField item)
 66    {
 867        if (!base.Remove(item))
 68        {
 469            return false;
 70        }
 71
 472        OnChanged();
 473        return true;
 74    }
 75
 76    internal new void RemoveAt(int index)
 77    {
 478        base.RemoveAt(index);
 479        OnChanged();
 480    }
 81
 82    internal new int RemoveAll(Predicate<ITaggedField> match)
 83    {
 484        var removed = base.RemoveAll(match);
 485        if (removed > 0)
 86        {
 487            OnChanged();
 88        }
 89
 490        return removed;
 91    }
 92
 93    internal new void RemoveRange(int index, int count)
 94    {
 495        base.RemoveRange(index, count);
 496        OnChanged();
 497    }
 98
 99    /// <summary>
 100    /// Try to get a tagged field of a specific type
 101    /// </summary>
 102    /// <param name="taggedFieldType">The type of the tagged field</param>
 103    /// <param name="taggedField">The tagged field</param>
 104    /// <typeparam name="T">The type of the tagged field</typeparam>
 105    /// <returns>True if the tagged field was found, false otherwise</returns>
 106    internal bool TryGet<T>(TaggedFieldTypes taggedFieldType, out T? taggedField) where T : ITaggedField
 107    {
 600108        var value = Get<T>(taggedFieldType);
 600109        if (value != null)
 110        {
 464111            taggedField = value;
 464112            return true;
 113        }
 114
 136115        taggedField = default!;
 136116        return false;
 117    }
 118
 119    /// <summary>
 120    /// Try to get all tagged fields of a specific type
 121    /// </summary>
 122    /// <param name="taggedFieldType">The type of the tagged field</param>
 123    /// <param name="taggedFieldList">A list containing the tagged fields</param>
 124    /// <typeparam name="T">The type of the tagged field</typeparam>
 125    /// <returns>True if the tagged fields were found, false otherwise</returns>
 126    internal bool TryGetAll<T>(TaggedFieldTypes taggedFieldType, out List<T> taggedFieldList) where T : ITaggedField
 127    {
 44128        var value = GetAll<T>(taggedFieldType);
 44129        if (value != null)
 130        {
 40131            taggedFieldList = value;
 40132            return true;
 133        }
 134
 4135        taggedFieldList = default!;
 4136        return false;
 137    }
 138
 139    /// <summary>
 140    /// Get a new TaggedFieldList from a BitReader
 141    /// </summary>
 142    /// <param name="bitReader">The BitReader to read from</param>
 143    /// <param name="network">The network type</param>
 144    /// <returns>A new TaggedFieldList</returns>
 145    internal static TaggedFieldList FromBitReader(BitReader bitReader, Network network)
 146    {
 68147        var taggedFields = new TaggedFieldList();
 924148        while (bitReader.HasMoreBits(15))
 149        {
 856150            var type = (TaggedFieldTypes)bitReader.ReadByteFromBits(5);
 856151            var length = bitReader.ReadInt16FromBits(10);
 856152            if (length == 0 || !bitReader.HasMoreBits(length * 5))
 153            {
 154                continue;
 155            }
 156
 344157            if (!Enum.IsDefined(typeof(TaggedFieldTypes), type))
 158            {
 12159                bitReader.SkipBits(length * 5);
 160            }
 161            else
 162            {
 163                try
 164                {
 332165                    var taggedField = TaggedFieldFactory.CreateTaggedFieldFromBitReader(type, bitReader, length, network
 312166                    if (taggedField.IsValid())
 167                    {
 168                        try
 169                        {
 312170                            taggedFields.Add(taggedField);
 312171                        }
 0172                        catch (Exception e)
 173                        {
 174                            Debug.WriteLine(e.Message);
 175                            // Skip for now, log latter
 0176                        }
 177                    }
 312178                }
 20179                catch (Exception e)
 180                {
 181                    Debug.WriteLine(e.Message);
 182                    // Skip for now, log latter
 20183                }
 184            }
 185        }
 186
 68187        return taggedFields;
 188    }
 189
 190    /// <summary>
 191    /// Write the TaggedFieldList to a BitWriter
 192    /// </summary>
 193    /// <param name="bitWriter">The BitWriter to write to</param>
 194    internal void WriteToBitWriter(BitWriter bitWriter)
 195    {
 736196        foreach (var taggedField in this)
 197        {
 198            // Write type
 292199            bitWriter.WriteByteAsBits((byte)taggedField.Type, 5);
 200
 201            // Write length
 292202            bitWriter.WriteInt16AsBits(taggedField.Length, 10);
 203
 292204            taggedField.WriteToBitWriter(bitWriter);
 205        }
 76206    }
 207
 208    /// <summary>
 209    /// Calculate the size of the TaggedFieldList in bits
 210    /// </summary>
 211    /// <returns>The size of the TaggedFieldList in bits</returns>
 212    internal int CalculateSizeInBits()
 213    {
 368214        return this.Sum(x => x.Length);
 215    }
 216
 217    /// <summary>
 218    /// Get a tagged field of a specific type
 219    /// </summary>
 220    /// <param name="taggedFieldType">The type of the tagged field</param>
 221    /// <typeparam name="T">The type of the tagged field</typeparam>
 222    /// <returns>The tagged field</returns>
 223    private T? Get<T>(TaggedFieldTypes taggedFieldType) where T : ITaggedField
 224    {
 2956225        return (T?)this.FirstOrDefault(x => x.Type.Equals(taggedFieldType));
 226    }
 227
 228    /// <summary>
 229    /// Get all tagged fields of a specific type
 230    /// </summary>
 231    /// <param name="taggedFieldType">The type of the tagged field</param>
 232    /// <typeparam name="T">The type of the tagged field</typeparam>
 233    /// <returns>A list containing the tagged fields</returns>
 234    private List<T>? GetAll<T>(TaggedFieldTypes taggedFieldType) where T : ITaggedField
 235    {
 208236        var taggedFields = this.Where(x => x.Type.Equals(taggedFieldType)).ToList();
 44237        return taggedFields.Count == 0
 44238            ? null
 44239            : taggedFields.Cast<T>().ToList();
 240    }
 241
 242    private void OnChanged()
 243    {
 892244        Changed?.Invoke(this, EventArgs.Empty);
 388245    }
 246}