bra_documents 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []