< Summary - Combined Code Coverage

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

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Type()100%210%
get_Value()100%210%
get_Length()100%210%
.ctor(...)0%4260%
WriteToBitWriter(...)0%620%
IsValid()0%620%
FromBitReader(...)0%4260%

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
 021    public TaggedFieldTypes Type => TaggedFieldTypes.Description;
 022    internal string Value { get; }
 023    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>
 029    internal DescriptionTaggedField(string value)
 30    {
 031        Value = value;
 32
 033        if (string.IsNullOrEmpty(value))
 34        {
 035            _data = [];
 036            Length = 0;
 37        }
 38        else
 39        {
 40            // Add Padding if needed
 041            var data = Encoding.UTF8.GetBytes(Value);
 042            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
 047            var bitLength = data.Length * 8;
 048            var totalBits = bitLength + (5 - bitLength % 5) % 5;
 049            if (totalBits != bitLength)
 50            {
 051                _data = new byte[data.Length + 1];
 052                Array.Copy(data, _data, data.Length);
 53            }
 54            else
 55            {
 056                _data = data;
 57            }
 58
 059            Length = (short)(totalBits / 5);
 60        }
 061    }
 62
 63    /// <inheritdoc/>
 64    public void WriteToBitWriter(BitWriter bitWriter)
 65    {
 066        if (Length == 0)
 067            return;
 68
 69        // Write data
 070        bitWriter.WriteBits(_data, Length * 5);
 071    }
 72
 73    /// <inheritdoc/>
 74    public bool IsValid()
 75    {
 76        // Field-level validation
 077        if (string.IsNullOrEmpty(Value))
 078            return true; // Empty description is valid
 79
 080        var utf8Bytes = Encoding.UTF8.GetBytes(Value);
 081        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:
 096                throw new ArgumentException(
 097                    $"Invalid length for {nameof(DescriptionTaggedField)}. Length must be greater or equal to 0",
 098                    nameof(length));
 99            case 0:
 0100                return new DescriptionTaggedField(string.Empty);
 101        }
 102
 103        // Read the data from the BitReader
 0104        var data = new byte[(length * 5 + 7) / 8];
 0105        bitReader.ReadBits(data, length * 5);
 106
 0107        return new DescriptionTaggedField(Encoding.UTF8.GetString(length * 5 % 8 > 0 ? data[..^1] : data));
 108    }
 109}