cnpj-alfanumerico 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6edb80cedd9d0fca254a0aacfe0a992d85bdee89323561972b10dcdffd3a1334
4
- data.tar.gz: 36eece67e9e563f4bed13dfd6078a33431c4ce4b13afc1b0cd79555541391267
3
+ metadata.gz: 5174d975e12103d3b6bc60b68e3e0be63ceb56d0d58b914beb26c8e56f506d54
4
+ data.tar.gz: ff0dd2c5e4306d21541da9bbcf4c4579b89669c9331041f4b3215130fed1b20b
5
5
  SHA512:
6
- metadata.gz: 6a0f489e3abcec7d74967df68b7937d77dd114b76f24198b3acafb0f7be665398a7defac1dddf4d0c5216caf724cfc721ff4e2b1808c04aed4ec5a049d9617fd
7
- data.tar.gz: bcc8e9094e3e6bd9ebdc6e5bfad4e3d56991a2df56cb14d4aa99c8b5b09ed54cb0c0900c08a4d81487de60f16a4dc3ce8b599f6bcc2680d586f7be630b15162a
6
+ metadata.gz: 9c571ca00452a58c0d519b9622e7b3b914db69a2874f01d359c4c88ab32b4fc0dcb9dbf50aca0402db5d78424a6a40cbf2ffdcae11f759ea6d582f48afcf58cb
7
+ data.tar.gz: 3df158439adbb6b9f73b01259afc1eab1dfe807d8a363f3ef99fbf3cb68108cb168e448bcc2bc0e10d137719bff4b6ca5e7c4ba11612de5121ab89ccc7e29455
data/CHANGELOG.md ADDED
@@ -0,0 +1,33 @@
1
+ # Changelog
2
+
3
+ ## 0.1.5
4
+
5
+ - Corrige o empacotamento da gem para incluir os arquivos em `lib/cnpj/**`.
6
+ - Resolve o `LoadError` ao carregar a gem em projetos Rails e Ruby `3.4`.
7
+
8
+ ## 0.1.4
9
+
10
+ - Passa a usar o environment `PROD` no workflow de publish para consumir `RUBYGEMS_AUTH_TOKEN` com escopo explícito.
11
+ - Alinha a próxima tag de release ao fluxo final de publicação automática no RubyGems.
12
+
13
+ ## 0.1.3
14
+
15
+ - Atualiza os workflows do GitHub Actions para `actions/checkout@v5` e `ruby/setup-ruby@v1`.
16
+ - Corrige compatibilidade do CI com `ubuntu-24.04` e versões Ruby `3.3` e `3.4`.
17
+ - Mantém o fluxo de release baseado em tag com a infraestrutura de CI já corrigida.
18
+
19
+ ## 0.1.2
20
+
21
+ - Simplifica a execução do CI para rodar testes sem depender de Bundler no GitHub Actions.
22
+ - Alinha a próxima tag de release com os workflows corrigidos de teste e publicação.
23
+
24
+ ## 0.1.1
25
+
26
+ - Adiciona `Gemfile` para integração mais previsível com Bundler e GitHub Actions.
27
+ - Atualiza a matriz de CI para Ruby `2.7`, `3.0`, `3.2`, `3.3` e `3.4`.
28
+ - Ajusta o workflow de release para publicar apenas por tag de versão.
29
+ - Documenta suporte oficial às versões modernas do Ruby.
30
+
31
+ ## 0.1.0
32
+
33
+ - Primeira versão com cálculo de DV, validação, geração e formatação de CNPJ numérico e alfanumérico.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Miguel C. Honorio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # cnpj-alfanumerico-ruby
2
+
3
+ Gem Ruby para validar, calcular, gerar e formatar CNPJ numérico e alfanumérico conforme as regras publicadas pela Receita Federal para vigência a partir de julho de 2026.
4
+
5
+ ## Compatibilidade
6
+
7
+ - Ruby `2.7`
8
+ - Ruby `3.0`
9
+ - Ruby `3.2`
10
+ - Ruby `3.3`
11
+ - Ruby `3.4`
12
+
13
+ O projeto usa apenas recursos básicos da linguagem e mantém CI para versões modernas do Ruby MRI.
14
+
15
+ ## Instalação
16
+
17
+ ```bash
18
+ gem install cnpj-alfanumerico
19
+ ```
20
+
21
+ ## Uso
22
+
23
+ ```ruby
24
+ require "cnpj-alfanumerico"
25
+
26
+ Cnpj::Alfanumerico.calculate_check_digits("12ABC34501DE")
27
+ # "35"
28
+
29
+ Cnpj::Alfanumerico.generate("12ABC34501DE")
30
+ # "12ABC34501DE35"
31
+
32
+ Cnpj::Alfanumerico.format("12ABC34501DE35")
33
+ # "12.ABC.345/01DE-35"
34
+
35
+ Cnpj::Alfanumerico.valid?("12.ABC.345/01DE-35")
36
+ # true
37
+ ```
38
+
39
+ ## API
40
+
41
+ - `Cnpj::Alfanumerico.normalize(value)`
42
+ - `Cnpj::Alfanumerico.char_value(char)`
43
+ - `Cnpj::Alfanumerico.calculate_check_digits(base12)`
44
+ - `Cnpj::Alfanumerico.generate(base12)`
45
+ - `Cnpj::Alfanumerico.valid?(cnpj)`
46
+ - `Cnpj::Alfanumerico.assert_valid!(cnpj)`
47
+ - `Cnpj::Alfanumerico.format(cnpj)`
48
+ - `Cnpj::Alfanumerico.formatted?(cnpj)`
49
+ - `Cnpj::Alfanumerico.split(cnpj)`
50
+
51
+ ## CLI
52
+
53
+ ```bash
54
+ exe/cnpj-alfanumerico validate 12.ABC.345/01DE-35
55
+ exe/cnpj-alfanumerico generate 12ABC34501DE
56
+ ```
57
+
58
+ ## Publicação
59
+
60
+ ```bash
61
+ gem build cnpj-alfanumerico.gemspec
62
+ gem push cnpj-alfanumerico-0.1.5.gem
63
+ ```
64
+
65
+ Para release automatizada via GitHub Actions, publique uma tag no formato `vX.Y.Z` que corresponda exatamente a `Cnpj::Alfanumerico::VERSION`.
66
+
67
+ ## Referências
68
+
69
+ - Receita Federal: projeto CNPJ alfanumérico
70
+ - Receita Federal: manual de cálculo do DV
@@ -0,0 +1,5 @@
1
+ module Cnpj
2
+ module Alfanumerico
3
+ VERSION = "0.1.5"
4
+ end
5
+ end
@@ -0,0 +1,91 @@
1
+ require_relative "alfanumerico/version"
2
+
3
+ module Cnpj
4
+ module Alfanumerico
5
+ BODY_LENGTH = 12
6
+ FULL_LENGTH = 14
7
+ FIRST_WEIGHTS = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2].freeze
8
+ SECOND_WEIGHTS = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2].freeze
9
+ BODY_PATTERN = /\A[0-9A-Z]{12}\z/.freeze
10
+ FULL_PATTERN = /\A[0-9A-Z]{12}[0-9]{2}\z/.freeze
11
+ FORMATTED_PATTERN = /\A([0-9A-Z]{2})([0-9A-Z]{3})([0-9A-Z]{3})([0-9A-Z]{4})([0-9]{2})\z/.freeze
12
+
13
+ module_function
14
+
15
+ def normalize(value)
16
+ value.to_s.gsub(/[^0-9A-Za-z]/, "").upcase
17
+ end
18
+
19
+ def formatted?(value)
20
+ /\A[0-9A-Z]{2}\.[0-9A-Z]{3}\.[0-9A-Z]{3}\/[0-9A-Z]{4}-[0-9]{2}\z/.match?(value.to_s.upcase)
21
+ end
22
+
23
+ def char_value(char)
24
+ code = char.to_s.upcase.ord
25
+ return code - 48 if code.between?(48, 57)
26
+ return code - 48 if code.between?(65, 90)
27
+
28
+ raise ArgumentError, "Invalid CNPJ character: #{char}"
29
+ end
30
+
31
+ def calculate_check_digits(base)
32
+ normalized = normalize(base)
33
+ raise ArgumentError, "Base CNPJ must contain exactly 12 alphanumeric characters." unless BODY_PATTERN.match?(normalized)
34
+
35
+ first_digit = compute_digit(normalized, FIRST_WEIGHTS)
36
+ second_digit = compute_digit("#{normalized}#{first_digit}", SECOND_WEIGHTS)
37
+
38
+ "#{first_digit}#{second_digit}"
39
+ end
40
+
41
+ def generate(base)
42
+ normalized = normalize(base)
43
+ "#{normalized}#{calculate_check_digits(normalized)}"
44
+ end
45
+
46
+ def valid?(value)
47
+ normalized = normalize(value)
48
+ return false unless FULL_PATTERN.match?(normalized)
49
+
50
+ base = normalized[0, BODY_LENGTH]
51
+ dv = normalized[BODY_LENGTH, 2]
52
+ calculate_check_digits(base) == dv
53
+ end
54
+
55
+ def assert_valid!(value)
56
+ normalized = normalize(value)
57
+ raise ArgumentError, "Invalid CNPJ." unless valid?(normalized)
58
+
59
+ normalized
60
+ end
61
+
62
+ def format(value)
63
+ normalized = normalize(value)
64
+ raise ArgumentError, "CNPJ must contain 12 alphanumeric characters followed by 2 numeric check digits." unless FULL_PATTERN.match?(normalized)
65
+
66
+ match = FORMATTED_PATTERN.match(normalized)
67
+ "#{match[1]}.#{match[2]}.#{match[3]}/#{match[4]}-#{match[5]}"
68
+ end
69
+
70
+ def split(value)
71
+ normalized = normalize(value)
72
+ raise ArgumentError, "Invalid CNPJ." unless FULL_PATTERN.match?(normalized)
73
+
74
+ {
75
+ raiz: normalized[0, 8],
76
+ ordem: normalized[8, 4],
77
+ dv: normalized[12, 2]
78
+ }
79
+ end
80
+
81
+ def compute_digit(base, weights)
82
+ sum = base.chars.each_with_index.sum do |char, index|
83
+ char_value(char) * weights[index]
84
+ end
85
+
86
+ remainder = sum % 11
87
+ remainder < 2 ? 0 : 11 - remainder
88
+ end
89
+ private_class_method :compute_digit
90
+ end
91
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cnpj-alfanumerico
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel C. Honorio
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-06 00:00:00.000000000 Z
11
+ date: 2026-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -47,10 +47,13 @@ executables:
47
47
  extensions: []
48
48
  extra_rdoc_files: []
49
49
  files:
50
+ - CHANGELOG.md
51
+ - LICENSE
52
+ - README.md
50
53
  - exe/cnpj-alfanumerico
51
54
  - lib/cnpj-alfanumerico.rb
52
- - test/cnpj_alfanumerico_test.rb
53
- - test/test_helper.rb
55
+ - lib/cnpj/alfanumerico.rb
56
+ - lib/cnpj/alfanumerico/version.rb
54
57
  homepage: https://github.com/miguelcarloshonorio/cpnj_ruby_2026
55
58
  licenses:
56
59
  - MIT
@@ -1,46 +0,0 @@
1
- require "test_helper"
2
-
3
- class CnpjAlfanumericoTest < Minitest::Test
4
- def test_normalizes_punctuation_and_lowercase
5
- assert_equal "12ABC34501DE35", Cnpj::Alfanumerico.normalize("12.abc.345/01de-35")
6
- end
7
-
8
- def test_maps_alphanumeric_values_using_ascii_minus_48
9
- assert_equal 0, Cnpj::Alfanumerico.char_value("0")
10
- assert_equal 9, Cnpj::Alfanumerico.char_value("9")
11
- assert_equal 17, Cnpj::Alfanumerico.char_value("A")
12
- assert_equal 42, Cnpj::Alfanumerico.char_value("Z")
13
- end
14
-
15
- def test_calculates_official_receita_example
16
- assert_equal "35", Cnpj::Alfanumerico.calculate_check_digits("12ABC34501DE")
17
- assert_equal "12ABC34501DE35", Cnpj::Alfanumerico.generate("12ABC34501DE")
18
- assert_equal "12.ABC.345/01DE-35", Cnpj::Alfanumerico.format("12ABC34501DE35")
19
- assert Cnpj::Alfanumerico.valid?("12.ABC.345/01DE-35")
20
- end
21
-
22
- def test_validates_legacy_numeric_cnpj
23
- assert Cnpj::Alfanumerico.valid?("11.444.777/0001-61")
24
- assert_equal "11.444.777/0001-61", Cnpj::Alfanumerico.format("11444777000161")
25
- end
26
-
27
- def test_rejects_invalid_values
28
- refute Cnpj::Alfanumerico.valid?("12.ABC.345/01DE-36")
29
- refute Cnpj::Alfanumerico.valid?("12.ABC.345/01DE-3X")
30
- assert_raises(ArgumentError) { Cnpj::Alfanumerico.calculate_check_digits("ABC") }
31
- end
32
-
33
- def test_splits_and_asserts_valid_cnpj
34
- assert_equal(
35
- { raiz: "12ABC345", ordem: "01DE", dv: "35" },
36
- Cnpj::Alfanumerico.split("12.ABC.345/01DE-35")
37
- )
38
- assert_equal "12ABC34501DE35", Cnpj::Alfanumerico.assert_valid!("12.ABC.345/01DE-35")
39
- assert_raises(ArgumentError) { Cnpj::Alfanumerico.assert_valid!("12.ABC.345/01DE-36") }
40
- end
41
-
42
- def test_detects_formatted_values
43
- assert Cnpj::Alfanumerico.formatted?("12.ABC.345/01DE-35")
44
- refute Cnpj::Alfanumerico.formatted?("12ABC34501DE35")
45
- end
46
- end
data/test/test_helper.rb DELETED
@@ -1,3 +0,0 @@
1
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
2
- require "minitest/autorun"
3
- require "cnpj-alfanumerico"