< Summary - Combined Code Coverage

Information
Class: NLightning.Bolt11.Models.TaggedFields.DescriptionTaggedField
Assembly: NLightning.Bolt11
File(s): /home/runner/work/nlightning/nlightning/src/NLightning.Bolt11/Models/TaggedFields/DescriptionTaggedField.cs
Tag: 49_19945309242
Line coverage
91%
Covered lines: 33
Uncovered lines: 3
Coverable lines: 36
Total lines: 109
Line coverage: 91.6%
Branch coverage
93%
Covered branches: 15
Total branches: 16
Branch coverage: 93.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Type()100%11100%
get_Value()100%11100%
get_Length()100%11100%
.ctor(...)83.33%6.17683.33%
WriteToBitWriter(...)100%22100%
IsValid()100%22100%
FromBitReader(...)100%66100%

File(s)

/home/runner/work/nlightning/nlightning/src/NLightning.Bolt11/Models/TaggedFields/DescriptionTaggedField.cs

#LineLine coverage
 1using System.Text;
 2
 3namespace NLightning.Bolt11.Models.TaggedFields;
 4
 5using Domain.Utils;
 6using Enums;
 7using Interfaces;
 8
 9/// <summary>
 10/// Tagged field for the description
 11/// </summary>
 12/// <remarks>
 13/// The description is a UTF-8 encoded string that describes, in short, the purpose of payment
 14/// </remarks>
 15/// <seealso cref="ITaggedField"/>
 16internal sealed class DescriptionTaggedField : ITaggedField
 17{
 18    private const int MaxDescriptionBytes = 639;
 19    private readonly byte[] _data;
 20
 136421    public TaggedFieldTypes Type => TaggedFieldTypes.Description;
 82022    internal string Value { get; }
 31623    public short Length { get; }
 24
 25    /// <summary>
 26    /// Initializes a new instance of the <see cref="DescriptionTaggedField"/> class.
 27    /// </summary>
 28    /// <param name="value">The Description</param>
 28029    internal DescriptionTaggedField(string value)
 30    {
 28031        Value = value;
 32
 28033        if (string.IsNullOrEmpty(value))
 34        {
 1635            _data = [];
 1636            Length = 0;
 37        }
 38        else
 39        {
 40            // Add Padding if needed
 26441            var data = Encoding.UTF8.GetBytes(Value);
 26442            if (data.Length > MaxDescriptionBytes)
 043                throw new ArgumentException(
 044                    $"Description exceeds maximum length of {MaxDescriptionBytes} UTF-8 bytes. Current: {data.Length} by
 045                    nameof(value));
 46
 26447            var bitLength = data.Length * 8;
 26448            var totalBits = bitLength + (5 - bitLength % 5) % 5;
 26449            if (totalBits != bitLength)
 50            {
 24451                _data = new byte[data.Length + 1];
 24452                Array.Copy(data, _data, data.Length);
 53            }
 54            else
 55            {
 2056                _data = data;
 57            }
 58
 26459            Length = (short)(totalBits / 5);
 60        }
 26461    }
 62
 63    /// <inheritdoc/>
 64    public void WriteToBitWriter(BitWriter bitWriter)
 65    {
 8066        if (Length == 0)
 467            return;
 68
 69        // Write data
 7670        bitWriter.WriteBits(_data, Length * 5);
 7671    }
 72
 73    /// <inheritdoc/>
 74    public bool IsValid()
 75    {
 76        // Field-level validation
 16477        if (string.IsNullOrEmpty(Value))
 878            return true; // Empty description is valid
 79
 15680        var utf8Bytes = Encoding.UTF8.GetBytes(Value);
 15681        return utf8Bytes.Length <= MaxDescriptionBytes;
 82    }
 83
 84    /// <summary>
 85    /// Reads a DescriptionTaggedField from a BitReader
 86    /// </summary>
 87    /// <param name="bitReader">The BitReader to read from</param>
 88    /// <param name="length">The length of the field</param>
 89    /// <returns>The DescriptionTaggedField</returns>
 90    /// <exception cref="ArgumentException">Thrown when the length is invalid</exception>
 91    internal static DescriptionTaggedField FromBitReader(BitReader bitReader, short length)
 92    {
 93        switch (length)
 94        {
 95            case < 0:
 496                throw new ArgumentException(
 497                    $"Invalid length for {nameof(DescriptionTaggedField)}. Length must be greater or equal to 0",
 498                    nameof(length));
 99            case 0:
 8100                return new DescriptionTaggedField(string.Empty);
 101        }
 102
 103        // Read the data from the BitReader
 80104        var data = new byte[(length * 5 + 7) / 8];
 80105        bitReader.ReadBits(data, length * 5);
 106
 80107        return new DescriptionTaggedField(Encoding.UTF8.GetString(length * 5 % 8 > 0 ? data[..^1] : data));
 108    }
 109}