< Summary - MechanicsSoftware — Coverage Report

Information
Class: MechanicsSoftware.Domain.ValueObjects.TaxId
Assembly: MechanicsSoftware.Domain
File(s): /home/runner/work/mechanics-software/mechanics-software/src/MechanicsSoftware.Domain/ValueObjects/TaxId.cs
Line coverage
98%
Covered lines: 65
Uncovered lines: 1
Coverable lines: 66
Total lines: 112
Line coverage: 98.4%
Branch coverage
95%
Covered branches: 23
Total branches: 24
Branch coverage: 95.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%210%
.ctor(...)100%66100%
OnlyDigits(...)100%11100%
IsValidCpf(...)100%44100%
CalculateCpfDigit(...)75%44100%
IsValidCnpj(...)100%44100%
CalculateCnpjDigit(...)100%66100%
AllDigitsEqual(...)100%11100%
GetEqualityComponents()100%11100%
ToString()100%11100%

File(s)

/home/runner/work/mechanics-software/mechanics-software/src/MechanicsSoftware.Domain/ValueObjects/TaxId.cs

#LineLine coverage
 1using System.Text.RegularExpressions;
 2using MechanicsSoftware.Domain.Enums;
 3using MechanicsSoftware.Domain.Exceptions;
 4
 5namespace MechanicsSoftware.Domain.ValueObjects;
 6
 7public sealed partial class TaxId : ValueObject
 8{
 9    [GeneratedRegex("[^0-9]")]
 10    private static partial Regex NonDigits();
 11
 12    public string Value { get; init; } = null!;
 13    public PersonType PersonType { get; init; }
 14
 015    private TaxId() { } // required for EF Core materialization
 16
 11617    public TaxId(string input, PersonType personType)
 11618    {
 11619        var digits = OnlyDigits(input);
 11620        PersonType = personType;
 21
 11622        if (personType == PersonType.INDIVIDUAL)
 10623        {
 10624            if (!IsValidCpf(digits))
 825                throw new DomainException("Invalid CPF.");
 9826        }
 27        else
 1028        {
 1029            if (!IsValidCnpj(digits))
 630                throw new DomainException("Invalid CNPJ.");
 431        }
 32
 10233        Value = digits;
 10234    }
 11635    private static string OnlyDigits(string input) => NonDigits().Replace(input, "");
 36
 37    // ================= CPF =================
 38    private static bool IsValidCpf(string cpf)
 10639    {
 10640        if (cpf.Length != 11)
 241            return false;
 42
 10443        if (AllDigitsEqual(cpf))
 444            return false;
 45
 10046        var firstDigit = CalculateCpfDigit(cpf[..9], 10);
 10047        var secondDigit = CalculateCpfDigit(cpf[..10], 11);
 48
 10049        return cpf.EndsWith($"{firstDigit}{secondDigit}", StringComparison.Ordinal);
 10650    }
 51
 52    private static int CalculateCpfDigit(string baseDigits, int weightStart)
 20053    {
 20054        var sum = 0;
 55
 420056        for (int i = 0; i < baseDigits.Length; i++)
 190057        {
 190058            sum += (baseDigits[i] - '0') * (weightStart - i);
 190059        }
 60
 20061        var remainder = sum % 11;
 20062        return remainder < 2 ? 0 : 11 - remainder;
 20063    }
 64
 65    // ================= CNPJ =================
 66    private static bool IsValidCnpj(string cnpj)
 1067    {
 1068        if (cnpj.Length != 14)
 269            return false;
 70
 871        if (AllDigitsEqual(cnpj))
 272            return false;
 73
 674        var firstDigit = CalculateCnpjDigit(cnpj[..12]);
 675        var secondDigit = CalculateCnpjDigit(cnpj[..12] + firstDigit);
 76
 677        return cnpj.EndsWith($"{firstDigit}{secondDigit}", StringComparison.Ordinal);
 1078    }
 79
 80    private static int CalculateCnpjDigit(string baseDigits)
 1281    {
 1282        int[] weights = baseDigits.Length == 12
 1283            ? new[] { 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 }
 1284            : new[] { 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 };
 85
 1286        var sum = 0;
 87
 32488        for (int i = 0; i < weights.Length; i++)
 15089        {
 15090            sum += (baseDigits[i] - '0') * weights[i];
 15091        }
 92
 1293        var remainder = sum % 11;
 1294        return remainder < 2 ? 0 : 11 - remainder;
 1295    }
 96
 97    private static bool AllDigitsEqual(string value)
 11298    {
 11299        return value.All(c => c == value[0]);
 112100    }
 101
 102    protected override IEnumerable<object?> GetEqualityComponents()
 12103    {
 12104        yield return Value;
 8105        yield return PersonType;
 8106    }
 107
 108    public override string ToString()
 2109    {
 2110        return Value;
 2111    }
 112}