cpf-val 0.0.0 → 1.0.0
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 +4 -4
- data/LICENSE +9 -0
- data/README.md +261 -0
- data/src/cpf-val/cpf_val.rb +25 -0
- data/src/cpf-val/cpf_validator.rb +65 -0
- data/src/cpf-val/errors.rb +36 -0
- data/src/cpf-val/types.rb +39 -0
- data/src/cpf-val/version.rb +1 -1
- data/src/cpf-val.rb +29 -4
- metadata +41 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 64fd7d1ae21ea1eb23f6901ba97deca775c993c15256c32907128e10a63f3f03
|
|
4
|
+
data.tar.gz: feeb0f0e0b9b9abe128b1b3228eb7c159cabc2ee2e85048c5ac08a3656289099
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dfd30fef2f1e3e7088b37f8cefeceb6e7b22df4ab436690c35b093fca92f26b307f0c454285e17e2aad9ab59e273f16f211970ad63aaa5b5dc3b7015d8b03eb9
|
|
7
|
+
data.tar.gz: 7aaba02ed1ad228409b79607c3ca755377f9f7d0cd0959c584506d28add7a428fdef920c59ffc9b8f4b46b965ca3ec86b4083dc4641b38291b4b9dcfbc6fff40
|
data/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Julio L. Muller
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
[](https://rubygems.org/gems/cpf-val)
|
|
4
|
+
[](https://rubygems.org/gems/cpf-val)
|
|
5
|
+
[](https://www.ruby-lang.org/)
|
|
6
|
+
[](https://github.com/LacusSolutions/br-utils-ruby/actions)
|
|
7
|
+
[](https://github.com/LacusSolutions/br-utils-ruby)
|
|
8
|
+
[](https://github.com/LacusSolutions/br-utils-ruby/blob/main/LICENSE)
|
|
9
|
+
|
|
10
|
+
> 🌎 [Acessar documentação em português](./README.pt.md)
|
|
11
|
+
|
|
12
|
+
A Ruby utility to validate CPF (Brazilian Individual's Taxpayer ID) values.
|
|
13
|
+
|
|
14
|
+
## Ruby Support
|
|
15
|
+
|
|
16
|
+
|  |  |  |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| Passing ✔ | Passing ✔ | Passing ✔ |
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- ✅ **Fixed 11-digit CPF**: Validates the standard 11-digit Brazilian CPF via the official modulo-11 algorithm
|
|
23
|
+
- ✅ **Flexible input**: Accepts `String` or `Array` of strings; array elements are concatenated in order
|
|
24
|
+
- ✅ **Format agnostic**: Strips every non-digit character before validation
|
|
25
|
+
- ✅ **Repeated-digit rejection**: All-identical-digit bases (e.g. `111.111.111-11`, `00000000000`) are rejected
|
|
26
|
+
- ✅ **Error handling**: Typed API-misuse errors with a `CpfVal::Error` marker for library-wide rescue
|
|
27
|
+
- ✅ **Minimal dependencies**: [`cpf-dv`](https://rubygems.org/gems/cpf-dv) for check-digit calculation and [`lacus-utils`](https://rubygems.org/gems/lacus-utils) for type descriptions in error messages
|
|
28
|
+
- ✅ **Dual API style**: Object-oriented (`CpfVal::CpfValidator`) and functional (`CpfVal.cpf_val`)
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
Install the gem directly:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
gem install cpf-val
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or add it to your `Gemfile` and run `bundle install`:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
gem 'cpf-val'
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Require
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
require 'cpf-val'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
require 'cpf-val'
|
|
54
|
+
|
|
55
|
+
validator = CpfVal::CpfValidator.new
|
|
56
|
+
|
|
57
|
+
validator.is_valid('12345678909') # => true
|
|
58
|
+
validator.is_valid('123.456.789-09') # => true
|
|
59
|
+
validator.is_valid('12345678910') # => false (invalid check digits)
|
|
60
|
+
validator.is_valid('00000000000') # => false (repeated digits)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Functional helper:
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
require 'cpf-val'
|
|
67
|
+
|
|
68
|
+
CpfVal.cpf_val('12345678909') # => true
|
|
69
|
+
CpfVal.cpf_val('123.456.789-09') # => true
|
|
70
|
+
CpfVal.cpf_val('12345678910') # => false
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
The main entry points are the class `CpfVal::CpfValidator` and the helper `CpfVal.cpf_val`.
|
|
76
|
+
|
|
77
|
+
### `CpfVal::CpfValidator`
|
|
78
|
+
|
|
79
|
+
- **`initialize`**: Takes no arguments. CPF validation has no configuration options.
|
|
80
|
+
- **`is_valid(cpf_input)`**: Validates a CPF value.
|
|
81
|
+
|
|
82
|
+
Input is normalized to a string (arrays of strings are concatenated). Every non-digit character is then stripped. If the sanitized length is not exactly **11**, its base is an all-identical-digit sequence, or the check digits do not match (`CpfDV::CpfCheckDigits` from **`cpf-dv`**), the method returns `false` — no exception is raised for validation failure.
|
|
83
|
+
|
|
84
|
+
If the input is not a `String` or an `Array` of strings, **`CpfVal::TypeMismatchError`** is raised.
|
|
85
|
+
|
|
86
|
+
```ruby
|
|
87
|
+
require 'cpf-val'
|
|
88
|
+
|
|
89
|
+
validator = CpfVal::CpfValidator.new
|
|
90
|
+
|
|
91
|
+
validator.is_valid('123.456.789-09') # => true
|
|
92
|
+
validator.is_valid('12345678909') # => true
|
|
93
|
+
validator.is_valid(['123', '456', '789', '09']) # => true
|
|
94
|
+
validator.is_valid('12345678910') # => false (invalid check digits)
|
|
95
|
+
validator.is_valid('11111111111') # => false (repeated digits)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Functional helper
|
|
99
|
+
|
|
100
|
+
`CpfVal.cpf_val` builds a new `CpfVal::CpfValidator` and calls `is_valid(cpf_input)` once. It takes only the input value:
|
|
101
|
+
|
|
102
|
+
```ruby
|
|
103
|
+
require 'cpf-val'
|
|
104
|
+
|
|
105
|
+
CpfVal.cpf_val('11144477735') # => true
|
|
106
|
+
CpfVal.cpf_val('111.444.777-35') # => true
|
|
107
|
+
CpfVal.cpf_val('11144477736') # => false
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Input formats
|
|
111
|
+
|
|
112
|
+
**String:** Plain digits or a formatted CPF (e.g. `123.456.789-09`, `499.784.420-90`, `011_258_960_00`). Non-digit characters are stripped before validation; the result must be exactly 11 digits.
|
|
113
|
+
|
|
114
|
+
**Array of strings:** Each element must be a `String`; values are concatenated (e.g. per digit, grouped segments, or mixed with punctuation). Non-string elements raise **`CpfVal::TypeMismatchError`**.
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
require 'cpf-val'
|
|
118
|
+
|
|
119
|
+
CpfVal.cpf_val(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '9']) # => true
|
|
120
|
+
CpfVal.cpf_val(['123.456', '789-09']) # => true
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Error handling
|
|
124
|
+
|
|
125
|
+
This package raises only for **API misuse** (wrong input type). Validation failures (wrong length, ineligible base such as repeated digits, invalid check digits) return `false` and do not raise.
|
|
126
|
+
|
|
127
|
+
Every custom error includes the `CpfVal::Error` marker module. This package defines **no** `CpfVal::DomainError` and no domain leaves — invalid CPF data never raises a domain error.
|
|
128
|
+
|
|
129
|
+
#### Summary
|
|
130
|
+
|
|
131
|
+
| Class | Inherits from | Category | Trigger condition |
|
|
132
|
+
|---|---|---|---|
|
|
133
|
+
| `CpfVal::TypeMismatchError` | `CpfVal::TypeMismatchError < TypeError < StandardError` (+ `include CpfVal::Error`) | API misuse | CPF input is not a `String` or `Array` of strings |
|
|
134
|
+
|
|
135
|
+
#### `CpfVal::Error` (marker module)
|
|
136
|
+
|
|
137
|
+
- **Inheritance:** module marker mixed into every library error via `include` (not a class).
|
|
138
|
+
- **Category:** N/A (rescue target only) — not a failure mode by itself.
|
|
139
|
+
- **When it is raised:** Never raised directly; included by every custom error the library raises.
|
|
140
|
+
- **Example:** N/A
|
|
141
|
+
- **How to rescue it:**
|
|
142
|
+
|
|
143
|
+
```ruby
|
|
144
|
+
rescue CpfVal::Error
|
|
145
|
+
# everything this library raises
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### `CpfVal::TypeMismatchError`
|
|
149
|
+
|
|
150
|
+
- **Inheritance:** `CpfVal::TypeMismatchError < TypeError < StandardError` (includes `CpfVal::Error`)
|
|
151
|
+
- **Category:** API misuse — the caller passed a value of the wrong type.
|
|
152
|
+
- **When it is raised:** Raised when the CPF input is not a `String` or an `Array` of strings (including when an array contains a non-string element).
|
|
153
|
+
- **Example:**
|
|
154
|
+
|
|
155
|
+
```ruby
|
|
156
|
+
require 'cpf-val'
|
|
157
|
+
|
|
158
|
+
begin
|
|
159
|
+
CpfVal.cpf_val(12_345_678_909)
|
|
160
|
+
rescue CpfVal::TypeMismatchError => e
|
|
161
|
+
puts e.message
|
|
162
|
+
# CPF input must be of type string or string[]. Got integer number.
|
|
163
|
+
end
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
- **How to rescue it:**
|
|
167
|
+
|
|
168
|
+
```ruby
|
|
169
|
+
rescue CpfVal::TypeMismatchError
|
|
170
|
+
# this library's type-contract violation
|
|
171
|
+
|
|
172
|
+
rescue TypeError
|
|
173
|
+
# native type errors, including this library's TypeMismatchError
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### Rescue granularity
|
|
177
|
+
|
|
178
|
+
Each level is shown as its own standalone example (do not merge them into one `rescue` ladder — a broad `TypeError` handler would make narrower clauses unreachable).
|
|
179
|
+
|
|
180
|
+
```ruby
|
|
181
|
+
require 'cpf-val'
|
|
182
|
+
|
|
183
|
+
# 1) Single native class — catches misuse errors of that kind,
|
|
184
|
+
# including non-library ones already handled elsewhere in the consumer's code.
|
|
185
|
+
begin
|
|
186
|
+
CpfVal.cpf_val(123)
|
|
187
|
+
rescue TypeError
|
|
188
|
+
# CpfVal::TypeMismatchError and any other TypeError (library or not)
|
|
189
|
+
end
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```ruby
|
|
193
|
+
require 'cpf-val'
|
|
194
|
+
|
|
195
|
+
# 2) CpfVal::DomainError — not applicable: this package defines no DomainError
|
|
196
|
+
# (and no domain leaves). Invalid CPF data returns false instead of raising.
|
|
197
|
+
# begin
|
|
198
|
+
# CpfVal.cpf_val(123)
|
|
199
|
+
# rescue CpfVal::DomainError # NameError — constant is not defined
|
|
200
|
+
# end
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```ruby
|
|
204
|
+
require 'cpf-val'
|
|
205
|
+
|
|
206
|
+
# 3) CpfVal::Error — catches everything the library raises, regardless of native ancestry.
|
|
207
|
+
begin
|
|
208
|
+
CpfVal.cpf_val(123)
|
|
209
|
+
rescue CpfVal::Error
|
|
210
|
+
# every custom error that includes CpfVal::Error
|
|
211
|
+
end
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
```ruby
|
|
215
|
+
require 'cpf-val'
|
|
216
|
+
|
|
217
|
+
# 4) Specific leaf class — catches only that exact failure mode.
|
|
218
|
+
begin
|
|
219
|
+
CpfVal.cpf_val(123)
|
|
220
|
+
rescue CpfVal::TypeMismatchError
|
|
221
|
+
# only CpfVal::TypeMismatchError
|
|
222
|
+
end
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Notable attributes on raised errors:
|
|
226
|
+
|
|
227
|
+
- `TypeMismatchError`: `actual_input`, `actual_type`, `expected_type`
|
|
228
|
+
|
|
229
|
+
## API
|
|
230
|
+
|
|
231
|
+
### Exports
|
|
232
|
+
|
|
233
|
+
After `require 'cpf-val'`:
|
|
234
|
+
|
|
235
|
+
- **`CpfVal.cpf_val`**: `(cpf_input) -> Boolean` — convenience helper.
|
|
236
|
+
- **`CpfVal::CpfValidator`**: Class to validate CPF (no options); accepts `String` or `Array<String>` in `is_valid`.
|
|
237
|
+
- **`CpfVal::CPF_LENGTH`**: `11` (constant).
|
|
238
|
+
- **`CpfVal::VERSION`**: gem version string.
|
|
239
|
+
- **Type predicate**: `CpfVal::CpfInput` — `CpfVal::CpfInput.accept?(value)` / `CpfVal::CpfInput === value` is true only for `String` or `Array<String>`.
|
|
240
|
+
- **Errors**: `CpfVal::Error`, `CpfVal::TypeMismatchError`.
|
|
241
|
+
|
|
242
|
+
## Contribution & Support
|
|
243
|
+
|
|
244
|
+
We welcome contributions! Please see our [Contributing Guidelines](https://github.com/LacusSolutions/br-utils-ruby/blob/main/CONTRIBUTING.md) for details. If you find this project helpful, please consider:
|
|
245
|
+
|
|
246
|
+
- ⭐ Starring the repository
|
|
247
|
+
- 🤝 Contributing to the codebase
|
|
248
|
+
- 💡 [Suggesting new features](https://github.com/LacusSolutions/br-utils-ruby/issues)
|
|
249
|
+
- 🐛 [Reporting bugs](https://github.com/LacusSolutions/br-utils-ruby/issues)
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
This project is licensed under the MIT License — see the [LICENSE](https://github.com/LacusSolutions/br-utils-ruby/blob/main/LICENSE) file for details.
|
|
254
|
+
|
|
255
|
+
## Changelog
|
|
256
|
+
|
|
257
|
+
See [CHANGELOG](./CHANGELOG.md) for a list of changes and version history.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
Made with ❤️ by [Lacus Solutions](https://github.com/LacusSolutions)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'cpf_validator'
|
|
4
|
+
|
|
5
|
+
module CpfVal
|
|
6
|
+
# Helper function to simplify the usage of the {CpfValidator} class.
|
|
7
|
+
#
|
|
8
|
+
# Validates a CPF string or array of strings and returns whether it is a valid
|
|
9
|
+
# Brazilian CPF. Invalid CPF data returns +false+; only API misuse raises
|
|
10
|
+
# documented errors.
|
|
11
|
+
#
|
|
12
|
+
# @param cpf_input [String, Array<String>] CPF value as a string or array of
|
|
13
|
+
# strings
|
|
14
|
+
# @return [Boolean] +true+ when valid, +false+ otherwise
|
|
15
|
+
# @raise [TypeMismatchError] if the input is not a +String+ or +Array<String>+
|
|
16
|
+
# @see CpfValidator#is_valid
|
|
17
|
+
# @see CpfValidator
|
|
18
|
+
#
|
|
19
|
+
# @example
|
|
20
|
+
# CpfVal.cpf_val('82911017366') # => true
|
|
21
|
+
# CpfVal.cpf_val('33528612691') # => false
|
|
22
|
+
def self.cpf_val(cpf_input)
|
|
23
|
+
CpfValidator.new.is_valid(cpf_input)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'cpf-dv'
|
|
4
|
+
|
|
5
|
+
require_relative 'errors'
|
|
6
|
+
require_relative 'types'
|
|
7
|
+
|
|
8
|
+
module CpfVal
|
|
9
|
+
# The standard length of a CPF (Cadastro de Pessoa Física) identifier (11
|
|
10
|
+
# digits).
|
|
11
|
+
CPF_LENGTH = 11
|
|
12
|
+
|
|
13
|
+
# Validator for CPF (Cadastro de Pessoa Física) identifiers.
|
|
14
|
+
#
|
|
15
|
+
# Validates CPF strings according to the Brazilian CPF validation algorithm.
|
|
16
|
+
# Invalid CPF data returns +false+; only API misuse raises documented errors.
|
|
17
|
+
class CpfValidator
|
|
18
|
+
NON_DIGIT_PATTERN = /\D/
|
|
19
|
+
|
|
20
|
+
private_constant :NON_DIGIT_PATTERN
|
|
21
|
+
|
|
22
|
+
# Validates a CPF input.
|
|
23
|
+
#
|
|
24
|
+
# A CPF is considered valid when, after stripping every non-digit character,
|
|
25
|
+
# it has exactly {CPF_LENGTH} digits, its base is not an all-identical-digit
|
|
26
|
+
# sequence, and both check digits match the ones computed via the standard
|
|
27
|
+
# modulo-11 algorithm. Invalid values return +false+ instead of raising.
|
|
28
|
+
#
|
|
29
|
+
# @param cpf_input [String, Array<String>] CPF value as a string or array of
|
|
30
|
+
# strings
|
|
31
|
+
# @return [Boolean] +true+ when valid, +false+ otherwise
|
|
32
|
+
# @raise [TypeMismatchError] if the input is not a +String+ or +Array<String>+
|
|
33
|
+
#
|
|
34
|
+
# @example
|
|
35
|
+
# CpfValidator.new.is_valid('82911017366') # => true
|
|
36
|
+
# rubocop:disable Naming/PredicatePrefix -- public API matches JS/Python `is_valid`
|
|
37
|
+
def is_valid(cpf_input)
|
|
38
|
+
actual_input = to_string_input(cpf_input)
|
|
39
|
+
sanitized_cpf = actual_input.gsub(NON_DIGIT_PATTERN, '')
|
|
40
|
+
|
|
41
|
+
return false unless sanitized_cpf.length == CPF_LENGTH
|
|
42
|
+
|
|
43
|
+
validate_with_check_digits(sanitized_cpf)
|
|
44
|
+
end
|
|
45
|
+
# rubocop:enable Naming/PredicatePrefix
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def to_string_input(cpf_input)
|
|
50
|
+
raise TypeMismatchError.new(cpf_input, 'string or string[]') unless CpfInput.accept?(cpf_input)
|
|
51
|
+
|
|
52
|
+
return cpf_input if cpf_input.is_a?(String)
|
|
53
|
+
|
|
54
|
+
cpf_input.join
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def validate_with_check_digits(sanitized_cpf)
|
|
58
|
+
cpf_check_digits = CpfDV::CpfCheckDigits.new(sanitized_cpf)
|
|
59
|
+
|
|
60
|
+
sanitized_cpf == cpf_check_digits.cpf
|
|
61
|
+
rescue CpfDV::Error
|
|
62
|
+
false
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'lacus-utils'
|
|
4
|
+
|
|
5
|
+
module CpfVal
|
|
6
|
+
# Marker module mixed into every custom error raised by this library.
|
|
7
|
+
#
|
|
8
|
+
# Use +rescue CpfVal::Error+ to catch every library error regardless of native
|
|
9
|
+
# ancestry.
|
|
10
|
+
module Error; end
|
|
11
|
+
|
|
12
|
+
# API misuse error raised when an argument's runtime type does not match the
|
|
13
|
+
# type required by the API contract (CPF input).
|
|
14
|
+
class TypeMismatchError < TypeError
|
|
15
|
+
include Error
|
|
16
|
+
|
|
17
|
+
# @return [Object] the offending input value
|
|
18
|
+
attr_reader :actual_input
|
|
19
|
+
|
|
20
|
+
# @return [String] human-readable type of {#actual_input}
|
|
21
|
+
attr_reader :actual_type
|
|
22
|
+
|
|
23
|
+
# @return [String] description of the expected type
|
|
24
|
+
attr_reader :expected_type
|
|
25
|
+
|
|
26
|
+
# @param actual_input [Object] the offending input value
|
|
27
|
+
# @param expected_type [String] description of the expected type
|
|
28
|
+
def initialize(actual_input, expected_type)
|
|
29
|
+
actual_type = LacusUtils.describe_type(actual_input)
|
|
30
|
+
super("CPF input must be of type #{expected_type}. Got #{actual_type}.")
|
|
31
|
+
@actual_input = actual_input
|
|
32
|
+
@actual_type = actual_type
|
|
33
|
+
@expected_type = expected_type
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CpfVal
|
|
4
|
+
# Case-equality predicate for CPF input: +String+ or +Array<String>+.
|
|
5
|
+
#
|
|
6
|
+
# Matches the runtime contract of {CpfValidator#is_valid} and {CpfVal.cpf_val}
|
|
7
|
+
# (same shape as +cpf-fmt+ / +cnpj-val+ input handling). Use
|
|
8
|
+
# {CpfInput.accept?} or +CpfInput === value+ (in +case+/+when+) to test
|
|
9
|
+
# candidacy without raising.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# CpfVal::CpfInput.accept?('82911017366') # => true
|
|
13
|
+
# CpfVal::CpfInput.accept?(%w[8 2 9 1 1]) # => true
|
|
14
|
+
# CpfVal::CpfInput.accept?(123) # => false
|
|
15
|
+
# CpfVal::CpfInput.accept?([1, 2, 3]) # => false
|
|
16
|
+
#
|
|
17
|
+
# @see CpfValidator#is_valid
|
|
18
|
+
# @see CpfVal.cpf_val
|
|
19
|
+
module CpfInput
|
|
20
|
+
class << self
|
|
21
|
+
# @param value [Object] candidate input
|
|
22
|
+
# @return [Boolean] whether +value+ is a +String+ or an +Array+ of +String+
|
|
23
|
+
def accept?(value)
|
|
24
|
+
return true if value.is_a?(String)
|
|
25
|
+
return false unless value.is_a?(Array)
|
|
26
|
+
|
|
27
|
+
value.all?(String)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Case-equality entry point for +case+/+when+ and +===+ checks.
|
|
31
|
+
#
|
|
32
|
+
# @param value [Object] candidate input
|
|
33
|
+
# @return [Boolean]
|
|
34
|
+
def ===(value)
|
|
35
|
+
accept?(value)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/src/cpf-val/version.rb
CHANGED
data/src/cpf-val.rb
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'cpf-dv'
|
|
4
3
|
require_relative 'cpf-val/version'
|
|
4
|
+
require_relative 'cpf-val/errors'
|
|
5
|
+
require_relative 'cpf-val/types'
|
|
6
|
+
require_relative 'cpf-val/cpf_validator'
|
|
7
|
+
require_relative 'cpf-val/cpf_val'
|
|
5
8
|
|
|
9
|
+
# Validates CPF (Cadastro de Pessoa Física) identifiers.
|
|
10
|
+
#
|
|
11
|
+
# Supports formatted or raw digit input. Invalid CPF data returns +false+; only
|
|
12
|
+
# documented errors are raised for API misuse (wrong input type).
|
|
13
|
+
#
|
|
14
|
+
# Errors fall into one category:
|
|
15
|
+
#
|
|
16
|
+
# - *API misuse* — the caller supplied a wrong type. Raised as
|
|
17
|
+
# {CpfVal::TypeMismatchError}.
|
|
18
|
+
#
|
|
19
|
+
# Every custom error includes the {CpfVal::Error} marker module so consumers can
|
|
20
|
+
# +rescue CpfVal::Error+ for a library-wide catch.
|
|
21
|
+
#
|
|
22
|
+
# Public API:
|
|
23
|
+
#
|
|
24
|
+
# - {CpfVal.cpf_val}
|
|
25
|
+
# - {CpfVal::CpfValidator}
|
|
26
|
+
# - {CpfVal::CPF_LENGTH}, {CpfVal::VERSION}
|
|
27
|
+
# - Type predicate: {CpfVal::CpfInput} (+String+ or +Array<String>+)
|
|
28
|
+
# - Error marker {CpfVal::Error}; misuse error {CpfVal::TypeMismatchError}
|
|
29
|
+
#
|
|
30
|
+
# @example
|
|
31
|
+
# require 'cpf-val'
|
|
32
|
+
#
|
|
33
|
+
# CpfVal.cpf_val('82911017366') # => true
|
|
6
34
|
module CpfVal
|
|
7
|
-
def self.hello
|
|
8
|
-
'cpf-val'
|
|
9
|
-
end
|
|
10
35
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cpf-val
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Julio L. Muller
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cpf-dv
|
|
@@ -16,26 +16,60 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 1.0.0
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: 1.1.0
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
26
|
requirements:
|
|
24
27
|
- - ">="
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
27
|
-
|
|
29
|
+
version: 1.0.0
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 1.1.0
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: lacus-utils
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 1.1.0
|
|
40
|
+
- - "<"
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: 2.0.0
|
|
43
|
+
type: :runtime
|
|
44
|
+
prerelease: false
|
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: 1.1.0
|
|
50
|
+
- - "<"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: 2.0.0
|
|
53
|
+
description: Utility to validate CPF (Brazilian Individual's Taxpayer ID)
|
|
28
54
|
email:
|
|
55
|
+
- juliolmuller@outlook.com
|
|
29
56
|
executables: []
|
|
30
57
|
extensions: []
|
|
31
58
|
extra_rdoc_files: []
|
|
32
59
|
files:
|
|
60
|
+
- LICENSE
|
|
61
|
+
- README.md
|
|
33
62
|
- src/cpf-val.rb
|
|
63
|
+
- src/cpf-val/cpf_val.rb
|
|
64
|
+
- src/cpf-val/cpf_validator.rb
|
|
65
|
+
- src/cpf-val/errors.rb
|
|
66
|
+
- src/cpf-val/types.rb
|
|
34
67
|
- src/cpf-val/version.rb
|
|
35
68
|
homepage: https://github.com/LacusSolutions/br-utils-ruby
|
|
36
69
|
licenses:
|
|
37
70
|
- MIT
|
|
38
71
|
metadata:
|
|
72
|
+
source_code_uri: https://github.com/LacusSolutions/br-utils-ruby
|
|
39
73
|
rubygems_mfa_required: 'true'
|
|
40
74
|
post_install_message:
|
|
41
75
|
rdoc_options: []
|
|
@@ -45,7 +79,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
45
79
|
requirements:
|
|
46
80
|
- - ">="
|
|
47
81
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: '3.
|
|
82
|
+
version: '3.1'
|
|
49
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
50
84
|
requirements:
|
|
51
85
|
- - ">="
|
|
@@ -55,5 +89,5 @@ requirements: []
|
|
|
55
89
|
rubygems_version: 3.4.19
|
|
56
90
|
signing_key:
|
|
57
91
|
specification_version: 4
|
|
58
|
-
summary: Validate CPF (Brazilian
|
|
92
|
+
summary: Validate CPF (Brazilian Individual's Taxpayer ID)
|
|
59
93
|
test_files: []
|