< Summary - Syki

Information
Class: Syki.Shared.StringExtensions
Assembly: Shared
File(s): /home/runner/work/syki/syki/Shared/Extensions/StringExtensions.cs
Tag: 4_16869239191
Line coverage
46%
Covered lines: 39
Uncovered lines: 45
Coverable lines: 84
Total lines: 225
Line coverage: 46.4%
Branch coverage
42%
Covered branches: 23
Total branches: 54
Branch coverage: 42.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
IsEmpty(...)100%22100%
IsIn(...)100%66100%
HasValue(...)100%11100%
HasValue(...)100%210%
OnlyNumbers(...)100%22100%
ToSnakeCase(...)75%44100%
GenerateTOTP(...)100%11100%
ToBase64(...)100%210%
Format(...)100%11100%
Format(...)100%210%
IsValidEmail(...)100%22100%
.cctor()100%11100%
Serialize(...)100%11100%
GenerateQrCodeBase64(...)100%11100%
MinutesToString(...)100%88100%
ToThousandSeparated(...)100%210%
ToTwo(...)0%620%
ToMinuteString(...)0%620%
ToMinuteString(...)0%620%
AddQueryString(...)100%210%
ConvertObjectToDictionary(...)0%110100%
ParseJsonString(...)0%620%
GetSqlSpanName(...)0%156120%

File(s)

/home/runner/work/syki/syki/Shared/Extensions/StringExtensions.cs

#LineLine coverage
 1using OtpNet;
 2using QRCoder;
 3using System.Text;
 4using Newtonsoft.Json;
 5using System.Reflection;
 6using System.Globalization;
 7using Newtonsoft.Json.Linq;
 8using Newtonsoft.Json.Converters;
 9using System.Text.RegularExpressions;
 10using Microsoft.Extensions.Primitives;
 11using Microsoft.AspNetCore.WebUtilities;
 12
 13namespace Syki.Shared;
 14
 15public static class StringExtensions
 16{
 17    public static bool IsEmpty(this string? text)
 18    {
 228619        return string.IsNullOrEmpty(text) || string.IsNullOrWhiteSpace(text);
 20    }
 21
 22    public static bool IsIn(this string? text, params string[] others)
 23    {
 7024        if (text.IsEmpty())
 625            return true;
 26
 30027        foreach (var other in others)
 28        {
 10229            if (other.Contains(text!, StringComparison.OrdinalIgnoreCase))
 3230                return true;
 31        }
 32
 3233        return false;
 34    }
 35
 36    public static bool HasValue(this string? text)
 37    {
 1251838        return !string.IsNullOrEmpty(text);
 39    }
 40
 41    public static bool HasValue(this StringValues text)
 42    {
 043        return !string.IsNullOrEmpty(text);
 44    }
 45
 46    public static string OnlyNumbers(this string text)
 47    {
 232648        if (text.HasValue())
 49        {
 230850            return new string(text.Where(char.IsDigit).ToArray());
 51        }
 52
 1853        return "";
 54    }
 55
 56    public static string ToSnakeCase(this string input)
 57    {
 23058        if (input.IsEmpty()) { return ""; }
 59
 21860        var startUnderscores = Regex.Match(input, @"^_+");
 21861        return startUnderscores + Regex.Replace(input, @"([a-z0-9])([A-Z])", "$1_$2").ToLower();
 62    }
 63
 64    public static string GenerateTOTP(this string key)
 65    {
 1066        var totp = new Totp(Base32Encoding.ToBytes(key));
 1067        return totp.ComputeTotp();
 68    }
 69
 70    public static string ToBase64(this string value)
 71    {
 072        var bytes = System.Text.Encoding.UTF8.GetBytes(value);
 073        return Convert.ToBase64String(bytes);
 74    }
 75
 76    public static string Format(this decimal value)
 77    {
 1078        return value.ToString("0.00", CultureInfo.InvariantCulture);
 79    }
 80
 81    public static string Format(this int value)
 82    {
 083        return value.ToString("N0", CultureInfo.CreateSpecificCulture("pt-BR"));
 84    }
 85
 86    public static bool IsValidEmail(this string email)
 87    {
 188888        if (email.IsEmpty()) return false;
 188089        return Regex.IsMatch(email, @"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?
 90    }
 91
 492    private static JsonSerializerSettings _settings = new()
 493    {
 494        Converters = [new StringEnumConverter()],
 495    };
 96
 97    public static string Serialize(this object obj)
 98    {
 551899        return JsonConvert.SerializeObject(obj, _settings);
 100    }
 101
 102    public static string GenerateQrCodeBase64(this string key, string email)
 103    {
 104        const string provider = "Syki";
 105
 18106        using var qrGenerator = new QRCodeGenerator();
 18107        using var qrCodeData = qrGenerator.CreateQrCode(
 18108            $"otpauth://totp/{provider}:{email}?secret={key}&issuer={provider}",
 18109            QRCodeGenerator.ECCLevel.Q
 18110        );
 111
 18112        var qrCode = new PngByteQRCode(qrCodeData);
 113
 18114        var bytes = qrCode.GetGraphic(20);
 115
 18116        return string.Format("data:image/png;base64,{0}", Convert.ToBase64String(bytes));
 18117    }
 118
 119    public static string MinutesToString(this int value)
 120    {
 32121        var hours = value / 60;
 32122        var minutes = value % 60;
 123
 34124        if (hours == 0 && minutes == 0) return "0";
 36125        if (hours == 0) return $"{minutes}min";
 40126        if (minutes == 0) return $"{hours}h";
 127
 8128        return $"{hours}h e {minutes}min";
 129    }
 130
 131    public static string ToThousandSeparated(this int value)
 132    {
 0133        return value.ToString("N0", CultureInfo.CreateSpecificCulture("pt-BR"));
 134    }
 135
 136    public static string ToTwo(this int value)
 137    {
 0138        return value < 10 ? $"0{value}" : value.ToString();
 139    }
 140
 141    public static string ToMinuteString(this DateTime date)
 142    {
 0143        if (date == DateTime.MinValue)
 0144            return "-";
 145
 0146        return date.ToLocalTime().ToString("dd/MM/yyyy HH:mm:ss");
 147    }
 148
 149    public static string ToMinuteString(this DateTime? date)
 150    {
 0151        if (date == null)
 0152            return "-";
 153
 0154        return date.Value.ToMinuteString();
 155    }
 156
 157    public static string AddQueryString(this string path, object obj)
 158    {
 0159        return QueryHelpers.AddQueryString(path, ConvertObjectToDictionary(obj));
 160    }
 161
 162    private static Dictionary<string, string?> ConvertObjectToDictionary(object obj)
 163    {
 0164        if (obj == null) return [];
 165
 0166        Dictionary<string, string?> dictionary = [];
 0167        PropertyInfo[] properties = obj.GetType().GetProperties();
 168
 0169        foreach (PropertyInfo property in properties)
 170        {
 0171            string propertyName = property.Name;
 0172            object propertyValue = property.GetValue(obj)!;
 173
 0174            if (propertyValue != null)
 175            {
 0176                var valueAsString = propertyValue.ToString();
 177
 0178                if (property.PropertyType == typeof(DateTime))
 0179                    valueAsString = ((DateTime)propertyValue).ToString("yyyy-MM-ddTHH:mm:sszzz");
 180
 0181                if (property.PropertyType == typeof(DateOnly))
 0182                    valueAsString = ((DateOnly)propertyValue).ToString("yyyy-MM-dd");
 183
 0184                dictionary.Add(propertyName, valueAsString);
 185            }
 186        }
 187
 0188        return dictionary;
 189    }
 190
 191    public static string ParseJsonString(this string input)
 192    {
 0193        if (input.IsEmpty()) return "";
 194
 195        try
 196        {
 0197            return JToken
 0198                .Parse(input)
 0199                .ToString(Formatting.Indented);
 200        }
 0201        catch
 202        {
 0203            return input;
 204        }
 0205    }
 206
 207    public static string GetSqlSpanName(this string sql)
 208    {
 0209        var comparer = StringComparison.InvariantCultureIgnoreCase;
 0210        var insert = sql.Contains("INSERT", comparer);
 0211        var update = sql.Contains("UPDATE", comparer);
 0212        var delete = sql.Contains("DELETE", comparer);
 0213        var select = sql.Contains("SELECT", comparer);
 214
 0215        var builder = new StringBuilder();
 216
 0217        if (insert) builder.Append("INSERT ");
 0218        if (update) builder.Append("UPDATE ");
 0219        if (delete) builder.Append("DELETE");
 220
 0221        if (!insert && !update && !delete && select) builder.Append("SELECT");
 222
 0223        return builder.ToString().Trim();
 224    }
 225}