Skip to content

Commit

Permalink
generate methods & more tests (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
leandromoh committed Jun 19, 2023
1 parent df5d53e commit 2688a26
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 30 deletions.
2 changes: 1 addition & 1 deletion benchmark/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void Setup()

CPFs = Enumerable
.Range(0, Count)
.Select(_ => CPF.GenerateUnformatted())
.Select(_ => CPF.Generate())
.ToArray();
}

Expand Down
40 changes: 36 additions & 4 deletions src/CNPJ.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,42 @@ internal static int CriaDigitoVerificador(ReadOnlySpan<int> cnpj, bool skipFirst
return total < 2 ? 0 : 11 - total;
}

public static string GenerateUnformatted()
public static string Generate()
{
Span<char> dest = stackalloc char[14];
Utils.GenerateImpl(dest, CriaDigitoVerificador);
return new string(dest);
Span<int> digits = stackalloc int[14];
Utils.GenerateImpl(digits, 8);
digits[8] = 0;
digits[9] = 0;
digits[10] = 0;
digits[11] = 1;
digits[12] = CriaDigitoVerificador(digits, true);
digits[13] = CriaDigitoVerificador(digits, false);
Span<char> chars = stackalloc char[14];
Utils.Cast(digits, chars);
return new string(chars);
}

public static string GenerateFormatted()
{
Span<int> digits = stackalloc int[14];
Utils.GenerateImpl(digits, 8);
digits[8] = 0;
digits[9] = 0;
digits[10] = 0;
digits[11] = 1;
digits[12] = CriaDigitoVerificador(digits, true);
digits[13] = CriaDigitoVerificador(digits, false);
Span<char> chars = stackalloc char[18];

Utils.Cast(digits.Slice(0, 2), chars.Slice(0, 2));
chars[2] = '.';
Utils.Cast(digits.Slice(2, 3), chars.Slice(3, 3));
chars[6] = '.';
Utils.Cast(digits.Slice(5, 3), chars.Slice(7, 3));
chars[10] = '/';
Utils.Cast(digits.Slice(8, 4), chars.Slice(11, 4));
chars[15] = '-';
Utils.Cast(digits.Slice(12, 2), chars.Slice(16, 2));
return new string(chars);
}
}
30 changes: 26 additions & 4 deletions src/CPF.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,32 @@ internal static int CriaDigitoVerificador(ReadOnlySpan<int> cpf, bool skipFirst)
return total < 2 ? 0 : 11 - total;
}

public static string GenerateUnformatted()
public static string Generate()
{
Span<char> dest = stackalloc char[11];
Utils.GenerateImpl(dest, CriaDigitoVerificador);
return new string(dest);
Span<int> digits = stackalloc int[11];
Utils.GenerateImpl(digits, 9);
digits[9] = CriaDigitoVerificador(digits, true);
digits[10] = CriaDigitoVerificador(digits, false);
Span<char> chars = stackalloc char[11];
Utils.Cast(digits, chars);
return new string(chars);
}

public static string GenerateFormatted()
{
Span<int> digits = stackalloc int[11];
Utils.GenerateImpl(digits, 9);
digits[9] = CriaDigitoVerificador(digits, true);
digits[10] = CriaDigitoVerificador(digits, false);
Span<char> chars = stackalloc char[14];

Utils.Cast(digits.Slice(0, 3), chars.Slice(0, 3));
chars[3] = '.';
Utils.Cast(digits.Slice(3, 3), chars.Slice(4, 3));
chars[7] = '.';
Utils.Cast(digits.Slice(6, 3), chars.Slice(8, 3));
chars[11] = '-';
Utils.Cast(digits.Slice(9, 2), chars.Slice(12, 2));
return new string(chars);
}
}
15 changes: 8 additions & 7 deletions src/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

internal delegate int SpanInt(ReadOnlySpan<int> span, bool skipFirst);

public class Utils
internal class Utils
{
private static readonly Random _random = new();

Expand All @@ -25,17 +25,18 @@ public static bool TryWriteNumbers(Span<int> digits, string value)
}

[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)]
internal static void GenerateImpl(Span<char> dest, SpanInt criaDigito)
public static void GenerateImpl(Span<int> digits, int len)
{
Span<int> digits = stackalloc int[dest.Length];
var len = dest.Length - 2;
for (var i = 0; i < len; i++)
digits[i] = _random.Next(0, 9);
}

digits[len] = criaDigito(digits, true);
digits[len + 1] = criaDigito(digits, false);
public static void Cast(Span<int> digits, Span<char> chars)
{
if (chars.Length != digits.Length)
return;

for (var i = 0; i < digits.Length; i++)
dest[i] = (char)(digits[i] + '0');
chars[i] = (char)(digits[i] + '0');
}
}
42 changes: 35 additions & 7 deletions test/CNPJTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ namespace DocumentoHelper.Test;
public class CNPJTest
{
[Theory]
[MemberData(nameof(GenerateCNPJSource))]
public void Validate_generated_values(string doc) =>
CNPJ.Validate(doc).Should().BeTrue();

[Theory]

// formatted

Expand Down Expand Up @@ -42,8 +37,41 @@ public class CNPJTest
public void Validate(string doc) =>
CNPJ.Validate(doc).Should().BeTrue();

public static IEnumerable<object[]> GenerateCNPJSource() =>
[Theory]
[InlineData("06@352(066)0001&27")]
[InlineData("11744$63*600%0164)")]
public void Validate_ignores_non_digits(string doc) =>
CNPJ.Validate(doc).Should().BeTrue();

[Theory]
[InlineData("--@#$%----06352066000127.............")]
[InlineData("¨#$%11¨%¨&*(744)(*63600%¨&*+++0;;;164")]
public void Validate_has_no_limit_for_string_length(string doc) =>
CNPJ.Validate(doc).Should().BeTrue();

[Theory]
[MemberData(nameof(GenerateSource))]
public void Validate_generate_values(string doc)
{
doc.Should().MatchRegex(@"^\d{8}0001\d{2}$");
CNPJ.Validate(doc).Should().BeTrue();
}

public static IEnumerable<object[]> GenerateSource() =>
Enumerable
.Range(0, 1000)
.Select(_ => new[] { CNPJ.Generate() });

[Theory]
[MemberData(nameof(GenerateFormattedSource))]
public void Validate_generate_formatted_values(string doc)
{
doc.Should().MatchRegex(@"^\d{2}\.\d{3}\.\d{3}/0001-\d{2}$");
CNPJ.Validate(doc).Should().BeTrue();
}

public static IEnumerable<object[]> GenerateFormattedSource() =>
Enumerable
.Range(0, 1000)
.Select(_ => new[] { CNPJ.GenerateUnformatted() });
.Select(_ => new[] { CNPJ.GenerateFormatted() });
}
42 changes: 35 additions & 7 deletions test/CPFTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ namespace DocumentoHelper.Test;
public class CPFTest
{
[Theory]
[MemberData(nameof(GenerateCPFSource))]
public void Validate_generated_values(string doc) =>
CPF.Validate(doc).Should().BeTrue();

[Theory]

// formatted

Expand Down Expand Up @@ -42,8 +37,41 @@ public class CPFTest
public void Validate(string doc) =>
CPF.Validate(doc).Should().BeTrue();

public static IEnumerable<object[]> GenerateCPFSource() =>
[Theory]
[InlineData("084@664_028#70")]
[InlineData("120+862!205(61")]
public void Validate_ignores_non_digits(string doc) =>
CPF.Validate(doc).Should().BeTrue();

[Theory]
[InlineData("--------084@664_028#70.............")]
[InlineData("()()()@@120+862!!!!205(61)(*&¨#@ %¨)")]
public void Validate_has_no_limit_for_string_length(string doc) =>
CPF.Validate(doc).Should().BeTrue();

[Theory]
[MemberData(nameof(GenerateSource))]
public void Validate_generate_values(string doc)
{
doc.Should().MatchRegex(@"^\d{11}$");
CPF.Validate(doc).Should().BeTrue();
}

public static IEnumerable<object[]> GenerateSource() =>
Enumerable
.Range(0, 1000)
.Select(_ => new[] { CPF.Generate() });

[Theory]
[MemberData(nameof(GenerateFormattedSource))]
public void Validate_generate_formatted_values(string doc)
{
doc.Should().MatchRegex(@"^\d{3}\.\d{3}\.\d{3}-\d{2}$");
CPF.Validate(doc).Should().BeTrue();
}

public static IEnumerable<object[]> GenerateFormattedSource() =>
Enumerable
.Range(0, 1000)
.Select(_ => new[] { CPF.GenerateUnformatted() });
.Select(_ => new[] { CPF.GenerateFormatted() });
}

0 comments on commit 2688a26

Please sign in to comment.