bra_documents 1.0.0 → 1.0.1

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: 215a2d930cbd6fe593e690469a1842c23f50fa3b9d7a486cbb1b71b6eab1c806
4
- data.tar.gz: 66c92be6ef85b40a4aa5bcb4bd248acc6b1ae5ffbe6e23ac718253acd1e06faf
3
+ metadata.gz: 9660c16de3e4c0e3af2ec9e235efb07afde5143c35bbf282c24c78675f91878e
4
+ data.tar.gz: e9b7de683720c392be7db09dff0e094e4e8c95699d3f31123143ad02c03a9575
5
5
  SHA512:
6
- metadata.gz: e9c46921964f8651778a6b8dcedc92be10be086d015c1b5a674a081670663abc4cd63112ab38a2e4a663123109146e74de6d43847f17e80bbc185524b7b2a68e
7
- data.tar.gz: cd3b29c4cbd6f10f29ee242647f53f09e5854b89cb57e77f0aacfd92cd120705ed3128ae9759cf89b0ce42b8e578c8a10e9a05dd5aead45c729ba35123b8953a
6
+ metadata.gz: 1b9fcfaf3bb6f3a398e5ea8ebfd9739cc4060bda3fbd7a3645122390a28890e2c2136eeeee6c579d9c2c9fc777e8625a62f535811de4e8994fdf379574124a96
7
+ data.tar.gz: 045fc875fdf40b830b93bc58c40afffab6c6b0185e421ebc39c005cd3daa6c2b4561885575f3c74247b7a1ab330996aaf8b8b3edb00af28524684cc4a35c767c
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ time: "09:00"
8
+ open-pull-requests-limit: 10
data/.travis.yml CHANGED
@@ -6,5 +6,7 @@ rvm:
6
6
  - 2.6.6
7
7
  - 2.5.8
8
8
  - 2.4.10
9
+ - 3.0.3
10
+ - 3.1.1
9
11
 
10
12
  before_install: gem install bundler -v 2.1.4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,6 @@
1
1
 
2
2
  # Changelog
3
+
3
4
  All notable changes to this project will be documented in this file.
4
5
 
5
6
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
@@ -7,10 +8,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7
8
 
8
9
  ## [Unreleased]
9
10
 
11
+ ## [1.0.1] - 2020-22-10
12
+
13
+ ### Added
14
+
15
+ - Add Formatter.raw method to make a document number to have only numbers;
16
+ - Add Matcher.match? to check if a CPF or CNPJ has a valid format;
17
+ - Add CPFGenerator.valid_verification_digit? to check if a CPF has a valid verification digit
18
+ - Add CNPJGenerator.valid_verification_digit? to check if a CNPJ has a valid verification digit
19
+
10
20
  ## [1.0.0] - 2020-22-10
21
+
11
22
  ### Added
12
- - CPF and CNPJ number formatter
13
- - CPF number generator
14
- - CNPJ number generator
15
- - RSpec CPF matcher helpers
16
- - RSpec CNPJ matcher helpers
23
+
24
+ - CPF and CNPJ number formatter;
25
+ - CPF number generator;
26
+ - CNPJ number generator;
27
+ - RSpec CPF matcher helpers;
28
+ - RSpec CNPJ matcher helpers;
data/Gemfile.lock CHANGED
@@ -1,33 +1,33 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bra_documents (1.0.0)
4
+ bra_documents (1.0.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  coderay (1.1.3)
10
- diff-lcs (1.4.4)
11
- method_source (0.9.2)
12
- pry (0.12.2)
13
- coderay (~> 1.1.0)
14
- method_source (~> 0.9.0)
15
- pry-nav (0.3.0)
16
- pry (>= 0.9.10, < 0.13.0)
17
- rake (13.0.1)
18
- rspec (3.9.0)
19
- rspec-core (~> 3.9.0)
20
- rspec-expectations (~> 3.9.0)
21
- rspec-mocks (~> 3.9.0)
22
- rspec-core (3.9.3)
23
- rspec-support (~> 3.9.3)
24
- rspec-expectations (3.9.2)
10
+ diff-lcs (1.5.0)
11
+ method_source (1.0.0)
12
+ pry (0.14.1)
13
+ coderay (~> 1.1)
14
+ method_source (~> 1.0)
15
+ pry-nav (1.0.0)
16
+ pry (>= 0.9.10, < 0.15)
17
+ rake (13.0.6)
18
+ rspec (3.11.0)
19
+ rspec-core (~> 3.11.0)
20
+ rspec-expectations (~> 3.11.0)
21
+ rspec-mocks (~> 3.11.0)
22
+ rspec-core (3.11.0)
23
+ rspec-support (~> 3.11.0)
24
+ rspec-expectations (3.11.0)
25
25
  diff-lcs (>= 1.2.0, < 2.0)
26
- rspec-support (~> 3.9.0)
27
- rspec-mocks (3.9.1)
26
+ rspec-support (~> 3.11.0)
27
+ rspec-mocks (3.11.0)
28
28
  diff-lcs (>= 1.2.0, < 2.0)
29
- rspec-support (~> 3.9.0)
30
- rspec-support (3.9.3)
29
+ rspec-support (~> 3.11.0)
30
+ rspec-support (3.11.0)
31
31
 
32
32
  PLATFORMS
33
33
  ruby
data/README.md CHANGED
@@ -40,6 +40,19 @@ BraDocuments::CPFGenerator.generate(person_number: '123123123', formatted: true)
40
40
  #=> "123.123.123-87"
41
41
  ```
42
42
 
43
+ ### CPF digit verification
44
+
45
+ ```rb
46
+ BraDocuments::CPFGenerator.valid_verification_digit?(document: '86027265892')
47
+ #=> true
48
+
49
+ BraDocuments::CPFGenerator.valid_verification_digit?(document: '123.123.123-87')
50
+ #=> true
51
+
52
+ BraDocuments::CPFGenerator.valid_verification_digit?(document: '123.123.123-88')
53
+ #=> false
54
+ ```
55
+
43
56
  ### CNPJ Generation
44
57
 
45
58
  ```rb
@@ -62,6 +75,19 @@ BraDocuments::CNPJGenerator.generate(company_number: '53855973', matrix_subsidia
62
75
  #=> "53.855.973/0001-79"
63
76
  ```
64
77
 
78
+ ### CNPJ digit verification
79
+
80
+ ```rb
81
+ BraDocuments::CNPJGenerator.valid_verification_digit?(document: '62885807804809')
82
+ #=> true
83
+
84
+ BraDocuments::CNPJGenerator.valid_verification_digit?(document: '53.855.973/0001-79')
85
+ #=> true
86
+
87
+ BraDocuments::CNPJGenerator.valid_verification_digit?(document: '53855973000177')
88
+ #=> false
89
+ ```
90
+
65
91
  ### Formatting
66
92
 
67
93
  ```rb
@@ -70,6 +96,25 @@ BraDocuments::Formatter.format('86027265892', as: :cpf)
70
96
 
71
97
  BraDocuments::Formatter.format('53855973879456', as: :cnpj)
72
98
  #=> "53.855.973/8794-56"
99
+
100
+ BraDocuments::Formatter.raw('53.855.973/8794-56')
101
+ #=> "53855973879456"
102
+ ```
103
+
104
+ ### Matching
105
+
106
+ ```rb
107
+ BraDocuments::Matcher.match?('11111111111', kind: :cpf, mode: :raw)
108
+ #=> true
109
+
110
+ BraDocuments::Matcher.match?('11111111111', kind: :cpf, mode: :formatted)
111
+ #=> false
112
+
113
+ BraDocuments::Matcher.match?('11111111111', kind: :cnpj, mode: :raw)
114
+ #=> false
115
+
116
+ BraDocuments::Matcher.match?('90.978.812/0001-07', kind: :cnpj, mode: :formatted)
117
+ #=> true
73
118
  ```
74
119
 
75
120
  ### Tests Matching
@@ -12,12 +12,27 @@ module BraDocuments
12
12
  # Generates a random CNPJ document number or add verifying digits to one if it's given.
13
13
  # It can return only numbers or formatted with mask
14
14
  #
15
- # BraDocuments::CNPJGenerator.generate # => "62885807804809"
16
- # BraDocuments::CNPJGenerator.generate(formatted: true) # => "53.855.973/0664-39"
17
- # BraDocuments::CNPJGenerator.generate(company_number: '53855973') # => "53855973879456"
18
- # BraDocuments::CNPJGenerator.generate(company_number: '53855973', formatted: true) # => "53.855.973/8189-02"
19
- # BraDocuments::CNPJGenerator.generate(company_number: '53855973', matrix_subsidiary_number: '0001') # => "53855973000179"
20
- # BraDocuments::CNPJGenerator.generate(company_number: '53855973', matrix_subsidiary_number: '0001', formatted: true) # => "53.855.973/0001-79"
15
+ # BraDocuments::CNPJGenerator.generate
16
+ # # => "62885807804809"
17
+ #
18
+ # BraDocuments::CNPJGenerator.generate(formatted: true)
19
+ # # => "53.855.973/0664-39"
20
+ #
21
+ # BraDocuments::CNPJGenerator.generate(company_number: '53855973')
22
+ # # => "53855973879456"
23
+ #
24
+ # BraDocuments::CNPJGenerator.generate(company_number: '53855973', formatted: true)
25
+ # # => "53.855.973/8189-02"
26
+ #
27
+ # BraDocuments::CNPJGenerator.generate(company_number: '53855973', matrix_subsidiary_number: '0001')
28
+ # # => "53855973000179"
29
+ #
30
+ # BraDocuments::CNPJGenerator.generate(
31
+ # company_number: '53855973',
32
+ # matrix_subsidiary_number: '0001',
33
+ # formatted: true
34
+ # )
35
+ # # => "53.855.973/0001-79"
21
36
  def generate(company_number: nil, matrix_subsidiary_number: nil, formatted: false)
22
37
  company_number = number_for('Company', COMPANY_NUMBER_SIZE, company_number)
23
38
  matrix_subsidiary_number = number_for('Matrix or subsidiary', MATRIX_SUBSIDIARY_SIZE, matrix_subsidiary_number)
@@ -28,6 +43,29 @@ module BraDocuments
28
43
  formatted ? Formatter.format(full_number, as: :cnpj) : full_number
29
44
  end
30
45
 
46
+ # Returns if a CPF has a valid verification digit.
47
+ #
48
+ # BraDocuments::CPFGenerator.valid_verification_digit?(document: '11.111.111/1111-11')
49
+ # # => false
50
+ #
51
+ # BraDocuments::CPFGenerator.valid_verification_digit?(document: '20.163.606/0001-55')
52
+ # # => true
53
+ #
54
+ # BraDocuments::CPFGenerator.valid_verification_digit?(document: '29432530000190')
55
+ # # => true
56
+ def valid_verification_digit?(document:)
57
+ raw_document = Formatter.raw(document)
58
+ return false if raw_document.chars.uniq.size == 1
59
+
60
+ company_number = raw_document.slice(0..(COMPANY_NUMBER_SIZE - 1))
61
+ matrix_subsidiary_number = raw_document
62
+ .slice(COMPANY_NUMBER_SIZE..(COMPANY_NUMBER_SIZE + MATRIX_SUBSIDIARY_SIZE - 1))
63
+ verified_digit = raw_document.slice(-2..-1)
64
+
65
+ generate(company_number: company_number, matrix_subsidiary_number: matrix_subsidiary_number)
66
+ .end_with?(verified_digit)
67
+ end
68
+
31
69
  private
32
70
 
33
71
  def verification_digit_multiplicators_for(numbers)
@@ -11,15 +11,42 @@ module BraDocuments
11
11
  # Generates a random CPF document number or add verifying digits to one if it's given.
12
12
  # It can return only numbers or formatted with mask
13
13
  #
14
- # BraDocuments::CPFGenerator.generate # => "86027265892"
15
- # BraDocuments::CPFGenerator.generate(formatted: true) # => "038.857.544-10"
16
- # BraDocuments::CPFGenerator.generate(person_number: '123123123') # => "12312312387"
17
- # BraDocuments::CPFGenerator.generate(person_number: '123123123', formatted: true) # => "123.123.123-87"
14
+ # BraDocuments::CPFGenerator.generate
15
+ # # => "86027265892"
16
+ #
17
+ # BraDocuments::CPFGenerator.generate(formatted: true)
18
+ # # => "038.857.544-10"
19
+ #
20
+ # BraDocuments::CPFGenerator.generate(person_number: '123123123')
21
+ # # => "12312312387"
22
+ #
23
+ # BraDocuments::CPFGenerator.generate(person_number: '123123123', formatted: true)
24
+ # # => "123.123.123-87"
18
25
  def generate(person_number: nil, formatted: false)
19
26
  numbers = number_for('Person', PERSON_NUMBER_SIZE, person_number)
20
27
  full_number = complete!(numbers)
21
28
 
22
- formatted ? Formatter.format(full_number, as: :cpf) : full_number
29
+ formatted ? Formatter.format(full_number, as: :cpf) : full_number
30
+ end
31
+
32
+ # Returns if a CPF has a valid verification digit.
33
+ #
34
+ # BraDocuments::CPFGenerator.valid_verification_digit?(document: '111.111.111-11')
35
+ # # => false
36
+ #
37
+ # BraDocuments::CPFGenerator.valid_verification_digit?(document: '123.456.700-88')
38
+ # # => true
39
+ #
40
+ # BraDocuments::CPFGenerator.valid_verification_digit?(document: '12345670088')
41
+ # # => true
42
+ def valid_verification_digit?(document:)
43
+ raw_document = Formatter.raw(document)
44
+ return false if raw_document.chars.uniq.size == 1
45
+
46
+ person_number = raw_document.slice(0..(PERSON_NUMBER_SIZE - 1))
47
+ verified_digit = raw_document.slice(PERSON_NUMBER_SIZE..(raw_document.size - 1))
48
+
49
+ generate(person_number: person_number).end_with?(verified_digit)
23
50
  end
24
51
 
25
52
  private
@@ -2,20 +2,47 @@
2
2
 
3
3
  module BraDocuments
4
4
  class Formatter
5
+ NOT_NUMBER = /\D/
5
6
  FORMATS = {
6
7
  cpf: { pattern: /\A(\d{3})(\d{3})(\d{3})(\d{2})\z/, mask: '%s.%s.%s-%s' },
7
- cnpj: { pattern: /\A(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})\z/, mask: '%s.%s.%s/%s-%s'}
8
+ cnpj: { pattern: /\A(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})\z/, mask: '%s.%s.%s/%s-%s' }
8
9
  }.freeze
9
10
 
10
- # Formats a only numbers CPF or CNPJ in their own mask
11
- #
12
- # BraDocuments::Formatter.format('86027265892', as: :cpf) # => "860.272.658-92"
13
- # BraDocuments::Formatter.format('53855973879456', as: :cnpj) # => "53.855.973/8794-56"
14
- def self.format(number, as:)
15
- format_data = FORMATS[as]
11
+ class << self
12
+ # Formats a only numbers CPF or CNPJ in their own mask
13
+ #
14
+ # BraDocuments::Formatter.format('86027265892', as: :cpf) # => "860.272.658-92"
15
+ # BraDocuments::Formatter.format('53855973879456', as: :cnpj) # => "53.855.973/8794-56"
16
+ def format(number, as:)
17
+ raise ArgumentError, "\"#{number.inspect}\" must be a String." unless number.is_a?(String)
18
+ unless known_format?(as)
19
+ raise ArgumentError, "Format \"#{as}\" is not know. Known formats: #{known_formats.join(', ')}."
20
+ end
16
21
 
17
- Kernel.format(format_data[:mask], *format_data[:pattern].match(number).captures)
22
+ format_data = FORMATS[as]
23
+
24
+ Kernel.format(format_data[:mask], *format_data[:pattern].match(number).captures)
25
+ end
26
+
27
+ # Formats removing all not number caracters from string.
28
+ #
29
+ # BraDocuments::Formatter.raw('860.272.658-9') # => "286027265892"
30
+ # BraDocuments::Formatter.format('53.855.973/8794-56') # => "53855973879456"
31
+ def raw(number)
32
+ raise ArgumentError, "\"#{number.inspect}\" must be a String." unless number.is_a?(String)
33
+
34
+ number.gsub(NOT_NUMBER, '')
35
+ end
36
+
37
+ private
38
+
39
+ def known_formats
40
+ @known_formats ||= FORMATS.keys
41
+ end
42
+
43
+ def known_format?(format)
44
+ known_formats.include?(format)
45
+ end
18
46
  end
19
47
  end
20
48
  end
21
-
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BraDocuments
4
+ class Matcher
5
+ FORMATS = {
6
+ cpf: { formatted: /\A(\d{3}\.){2}\d{3}-\d{2}\z/, raw: /\A\d{11}\z/ },
7
+ cnpj: { formatted: /\A\d{2}.\d{3}\.\d{3}\/\d{4}-\d{2}\z/, raw: /\A\d{14}\z/ }
8
+ }.freeze
9
+
10
+ class << self
11
+ # Macthes with Brazilian CPF and CNPJ documents.
12
+ #
13
+ # BraDocuments::Matcher.match?('11111111111', kind: :cpf, mode: :raw)
14
+ # # => true
15
+ #
16
+ # BraDocuments::Matcher.match?('11111111111', kind: :cpf, mode: :formatted)
17
+ # # => false
18
+ #
19
+ # BraDocuments::Matcher.match?('11111111111', kind: :cnpj, mode: :raw)
20
+ # # => false
21
+ #
22
+ # BraDocuments::Matcher.match?('90.978.812/0001-07', kind: :cnpj, mode: :formatted)
23
+ # # => true
24
+ def match?(number, kind:, mode:)
25
+ raise ArgumentError, "\"#{number.inspect}\" must be a String." unless number.is_a?(String)
26
+
27
+ unless known_format?(kind)
28
+ raise ArgumentError, "Unknown document kind \"#{kind.inspect}\". Known documents: #{known_formats.join(', ')}."
29
+ end
30
+
31
+ unless known_mode?(mode)
32
+ raise ArgumentError, "Unknown document format mode \"#{mode.inspect}\". Known modes: #{known_modes.join(', ')}."
33
+ end
34
+
35
+ formats_to_match(kind, mode).any? { |format| format.match?(number) }
36
+ end
37
+
38
+ private
39
+
40
+ def known_formats
41
+ @known_formats ||= FORMATS.keys
42
+ end
43
+
44
+ def known_modes
45
+ @known_modes ||= FORMATS[known_formats.first].keys << :any
46
+ end
47
+
48
+ def known_format?(format)
49
+ known_formats.include?(format)
50
+ end
51
+
52
+ def known_mode?(mode)
53
+ known_modes.include?(mode)
54
+ end
55
+
56
+ def formats_to_match(kind, mode)
57
+ document_formats = FORMATS[kind]
58
+
59
+ mode == :any ? document_formats.values : [document_formats[mode]]
60
+ end
61
+ end
62
+ end
63
+ end
@@ -3,7 +3,6 @@
3
3
  module BraDocuments
4
4
  class NationalRegisterBase
5
5
  class << self
6
- NOT_NUMBER_PATTERN = /\D/.freeze
7
6
  BASE = 11
8
7
 
9
8
  private
@@ -14,9 +13,12 @@ module BraDocuments
14
13
  end
15
14
 
16
15
  def number_for(number_description, number_size, given_value)
17
- given_value = only_digits_for(given_value)
16
+ given_value = Formatter.raw(given_value.to_s)
18
17
  if !given_value.to_s.empty?
19
- raise ArgumentError, "#{number_description} number must be a number with #{number_size} digits." unless given_value.size == number_size
18
+ unless given_value.size == number_size
19
+ raise ArgumentError, "#{number_description} number must be a number with #{number_size} digits."
20
+ end
21
+
20
22
  given_value.split('').map(&:to_i)
21
23
  else
22
24
  number_with(number_size)
@@ -27,10 +29,6 @@ module BraDocuments
27
29
  size.times.map { rand(10) }
28
30
  end
29
31
 
30
- def only_digits_for(number)
31
- number.to_s.gsub(NOT_NUMBER_PATTERN, '')
32
- end
33
-
34
32
  def verification_digit_for(numbers)
35
33
  verification_digit_multiplicators = verification_digit_multiplicators_for(numbers)
36
34
  sum_and_multiplication = sum_and_multiply(numbers, verification_digit_multiplicators)
@@ -43,7 +41,8 @@ module BraDocuments
43
41
  end
44
42
 
45
43
  def sum_and_multiply(numbers, multiplicators)
46
- multiplicators.map
44
+ multiplicators
45
+ .map
47
46
  .with_index { |multiplicator, position| numbers[position] * multiplicator }
48
47
  .sum
49
48
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BraDocuments
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.1'
5
5
  end
data/lib/bra_documents.rb CHANGED
@@ -4,8 +4,8 @@ require 'bra_documents/national_register_base'
4
4
  require 'bra_documents/cpf_generator'
5
5
  require 'bra_documents/cnpj_generator'
6
6
  require 'bra_documents/formatter'
7
- require "bra_documents/version"
8
-
7
+ require 'bra_documents/matcher'
8
+ require 'bra_documents/version'
9
9
 
10
10
  module BraDocuments
11
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bra_documents
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Vicenzo
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-22 00:00:00.000000000 Z
11
+ date: 2022-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -74,6 +74,7 @@ executables: []
74
74
  extensions: []
75
75
  extra_rdoc_files: []
76
76
  files:
77
+ - ".github/dependabot.yml"
77
78
  - ".gitignore"
78
79
  - ".rspec"
79
80
  - ".travis.yml"
@@ -91,6 +92,7 @@ files:
91
92
  - lib/bra_documents/cnpj_generator.rb
92
93
  - lib/bra_documents/cpf_generator.rb
93
94
  - lib/bra_documents/formatter.rb
95
+ - lib/bra_documents/matcher.rb
94
96
  - lib/bra_documents/national_register_base.rb
95
97
  - lib/bra_documents/testing/rspec.rb
96
98
  - lib/bra_documents/testing/rspec/matchers/cnpj_matcher.rb
@@ -104,7 +106,7 @@ metadata:
104
106
  homepage_uri: https://github.com/bvicenzo/bra_documents
105
107
  source_code_uri: https://github.com/bvicenzo/bra_documents
106
108
  changelog_uri: https://github.com/bvicenzo/bra_documents/blob/master/CHANGELOG.md
107
- post_install_message:
109
+ post_install_message:
108
110
  rdoc_options: []
109
111
  require_paths:
110
112
  - lib
@@ -119,8 +121,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
121
  - !ruby/object:Gem::Version
120
122
  version: '0'
121
123
  requirements: []
122
- rubygems_version: 3.1.4
123
- signing_key:
124
+ rubygems_version: 3.3.7
125
+ signing_key:
124
126
  specification_version: 4
125
127
  summary: A implementation for generating Brazilian CPF and CNPJ document numbers.
126
128
  test_files: []