amka 2.0.0 → 2.1.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/CHANGELOG.md +19 -0
- data/README.md +19 -4
- data/lib/amka/luhn.rb +27 -0
- data/lib/amka/version.rb +1 -1
- data/lib/amka.rb +117 -5
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de5ab67f3f55def8127fdcc62f80227e3a1eac67310f5505fb0d2bd885235b5e
|
4
|
+
data.tar.gz: 8898093154bfa16391dbf6721204350f4f2052088db0db2be4dc0ee8cda51e38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e46d541a313fd37f7d58f98d244459110d77d22630e65d2b8941fa7c5a4a69f1d0eb8e50962acd6d7e83bec5f6b4fa227e8c1d8e3c9ef8a01c9bbd2b2589b15
|
7
|
+
data.tar.gz: d2b9da885d006f520a93b4a08f07561f5518b1369f16fd9c40da0a78560cee23edef7a49359e9addf8c0ec1cbeed401ebcf0159870d37325fb87ebf07a483faa
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [2.1.0] - 2023-05-14
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- New `validate` method that returns detailed validation errors
|
13
|
+
- New `validate!` method that raises exceptions with descriptive messages
|
14
|
+
- Added `safe_valid?` method to Luhn class for exception-free validation
|
15
|
+
- Improved error handling with specific `ValidationError` class
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
- Improved `valid?` method to never raise exceptions
|
20
|
+
- Refactored validation logic for better maintainability
|
21
|
+
- Better error messages for validation failures
|
22
|
+
|
23
|
+
### Fixed
|
24
|
+
|
25
|
+
- Rubocop compliance for method length
|
26
|
+
|
8
27
|
## [2.0.0] - 2025-04-16
|
9
28
|
|
10
29
|
### Changed
|
data/README.md
CHANGED
@@ -56,16 +56,31 @@ gem install amka
|
|
56
56
|
```ruby
|
57
57
|
require 'amka'
|
58
58
|
|
59
|
-
#
|
59
|
+
# Simple Validation (returns true or false)
|
60
60
|
Amka.valid?('01011441432')
|
61
|
-
# returns false
|
62
|
-
# it belonged to a real person!!!!)
|
61
|
+
# returns false
|
63
62
|
|
64
63
|
# You can also pass the 4 digit year of birth as a second string argument
|
65
64
|
# This will increase the accuracy of the date part of validation to 100%.
|
66
65
|
Amka.valid?('111098xxxxx', '1998')
|
67
66
|
|
68
|
-
#
|
67
|
+
# Detailed Validation with Error Messages
|
68
|
+
errors = Amka.validate('01AB9012345')
|
69
|
+
if errors.empty?
|
70
|
+
puts "Valid AMKA!"
|
71
|
+
else
|
72
|
+
puts "Invalid AMKA: #{errors.join(', ')}"
|
73
|
+
# => "Invalid AMKA: AMKA must contain only digits"
|
74
|
+
end
|
75
|
+
|
76
|
+
# Exception-based Validation
|
77
|
+
begin
|
78
|
+
Amka.validate!('01019012345') # Returns true if valid
|
79
|
+
rescue Amka::ValidationError => e
|
80
|
+
puts "Error: #{e.message}"
|
81
|
+
end
|
82
|
+
|
83
|
+
# To generate a random AMKA (returns the AMKA as a string)
|
69
84
|
Amka.generate
|
70
85
|
|
71
86
|
# To generate with a specific date (date format: [d]d/[m]m/yyyy)
|
data/lib/amka/luhn.rb
CHANGED
@@ -50,6 +50,33 @@ module Amka
|
|
50
50
|
(digits_sum % 10).zero?
|
51
51
|
end
|
52
52
|
|
53
|
+
# Validates if a given ID follows the Luhn algorithm, without raising exceptions
|
54
|
+
#
|
55
|
+
# This is a safe version of valid? that returns false for any invalid input
|
56
|
+
# instead of raising exceptions. It's designed for use in validation pipelines
|
57
|
+
# where exceptions would need to be caught.
|
58
|
+
#
|
59
|
+
# @param luhn_id [Object] the ID to validate
|
60
|
+
# @return [Boolean] true if valid according to Luhn algorithm, false otherwise
|
61
|
+
# @example Safe validation with clean inputs
|
62
|
+
# Amka::Luhn.safe_valid?('4532015112830366') #=> true
|
63
|
+
# @example Safe validation with problematic inputs
|
64
|
+
# Amka::Luhn.safe_valid?(nil) #=> false
|
65
|
+
# Amka::Luhn.safe_valid?(12345) #=> false
|
66
|
+
# Amka::Luhn.safe_valid?('abc-123') #=> false
|
67
|
+
def self.safe_valid?(luhn_id)
|
68
|
+
# Return false for non-string input
|
69
|
+
return false unless luhn_id.is_a?(String)
|
70
|
+
# Return false for strings with non-digits
|
71
|
+
return false unless luhn_id.match(/\A\d+\Z/)
|
72
|
+
|
73
|
+
digits_sum = calculate_digits_sum(luhn_id)
|
74
|
+
(digits_sum % 10).zero?
|
75
|
+
rescue StandardError
|
76
|
+
# Catch any unexpected errors and return false
|
77
|
+
false
|
78
|
+
end
|
79
|
+
|
53
80
|
# Generates a valid Luhn ID
|
54
81
|
#
|
55
82
|
# Creates a number that passes the Luhn check by:
|
data/lib/amka/version.rb
CHANGED
data/lib/amka.rb
CHANGED
@@ -31,6 +31,9 @@ module Amka
|
|
31
31
|
# Standard error class for the Amka gem
|
32
32
|
class Error < StandardError; end
|
33
33
|
|
34
|
+
# Error raised when AMKA format or content is invalid
|
35
|
+
class ValidationError < Error; end
|
36
|
+
|
34
37
|
# Validates whether a given string is a valid AMKA
|
35
38
|
#
|
36
39
|
# The validation checks three conditions:
|
@@ -38,7 +41,10 @@ module Amka
|
|
38
41
|
# 2. The first 6 digits must form a valid date (DDMMYY format)
|
39
42
|
# 3. The entire number must satisfy the Luhn algorithm check
|
40
43
|
#
|
41
|
-
#
|
44
|
+
# This method will always return a boolean and never raise exceptions,
|
45
|
+
# returning false for any input that doesn't meet the AMKA criteria.
|
46
|
+
#
|
47
|
+
# @param amka [Object] the AMKA to validate, should be a string containing only digits
|
42
48
|
# @param year [String, nil] optional four-digit year to match against
|
43
49
|
# When provided, improves the validation by ensuring the birth year
|
44
50
|
# matches exactly (resolves century ambiguity in 2-digit years)
|
@@ -47,14 +53,120 @@ module Amka
|
|
47
53
|
# Amka.valid?('17019012345') #=> true
|
48
54
|
# @example Validating with explicit year
|
49
55
|
# Amka.valid?('17019012345', '1990') #=> true
|
56
|
+
# @example Validating invalid input
|
57
|
+
# Amka.valid?(nil) #=> false
|
58
|
+
# Amka.valid?(12345) #=> false
|
59
|
+
# Amka.valid?('abc123') #=> false
|
50
60
|
def self.valid?(amka, year = nil)
|
51
|
-
|
52
|
-
|
61
|
+
# Return false for non-string input
|
62
|
+
return false unless amka.is_a?(String)
|
63
|
+
# Return false for strings with non-digits
|
64
|
+
return false unless amka.match(/\A\d+\Z/)
|
65
|
+
# Check length requirement
|
53
66
|
return false unless length_is_11?(amka)
|
54
67
|
|
55
|
-
|
68
|
+
# Check if date and Luhn algorithm are valid
|
69
|
+
begin
|
70
|
+
return false unless Utils.valid_date?(amka, year)
|
56
71
|
|
57
|
-
|
72
|
+
Luhn.safe_valid?(amka)
|
73
|
+
rescue ArgumentError
|
74
|
+
# If any validation raises an exception, the AMKA is invalid
|
75
|
+
false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Validates an AMKA and returns an array of validation errors
|
80
|
+
#
|
81
|
+
# This method provides detailed feedback about why validation failed,
|
82
|
+
# returning an empty array for valid AMKAs or an array of error messages
|
83
|
+
# for invalid ones.
|
84
|
+
#
|
85
|
+
# @param amka [Object] the AMKA to validate
|
86
|
+
# @param year [String, nil] optional four-digit year to match against
|
87
|
+
# @return [Array<String>] empty array if valid, otherwise contains error messages
|
88
|
+
# @example Get validation errors
|
89
|
+
# errors = Amka.validate(input)
|
90
|
+
# if errors.empty?
|
91
|
+
# puts "Valid AMKA!"
|
92
|
+
# else
|
93
|
+
# puts "Invalid AMKA: #{errors.join(', ')}"
|
94
|
+
# end
|
95
|
+
def self.validate(amka, year = nil)
|
96
|
+
errors = []
|
97
|
+
|
98
|
+
# Check for basic format issues and return early if found
|
99
|
+
basic_format_errors = check_basic_format(amka)
|
100
|
+
return basic_format_errors unless basic_format_errors.empty?
|
101
|
+
|
102
|
+
# Check length
|
103
|
+
errors << 'AMKA must be exactly 11 digits long' unless length_is_11?(amka)
|
104
|
+
|
105
|
+
# Check date format
|
106
|
+
check_date(errors, amka, year)
|
107
|
+
|
108
|
+
# Check Luhn algorithm
|
109
|
+
check_luhn(errors, amka)
|
110
|
+
|
111
|
+
errors
|
112
|
+
end
|
113
|
+
|
114
|
+
# Helper method to validate basic format requirements
|
115
|
+
# @return [Array<String>] empty if valid, otherwise contains error message
|
116
|
+
def self.check_basic_format(amka)
|
117
|
+
errors = []
|
118
|
+
|
119
|
+
unless amka.is_a?(String)
|
120
|
+
errors << 'AMKA must be a string'
|
121
|
+
return errors
|
122
|
+
end
|
123
|
+
|
124
|
+
errors << 'AMKA must contain only digits' unless amka.match(/\A\d+\Z/)
|
125
|
+
|
126
|
+
errors
|
127
|
+
end
|
128
|
+
private_class_method :check_basic_format
|
129
|
+
|
130
|
+
# Helper method to validate date format
|
131
|
+
def self.check_date(errors, amka, year)
|
132
|
+
unless Utils.valid_date?(amka, year)
|
133
|
+
errors << 'First 6 digits of AMKA must form a valid date (DDMMYY)'
|
134
|
+
end
|
135
|
+
rescue ArgumentError
|
136
|
+
errors << 'Invalid date format in AMKA'
|
137
|
+
end
|
138
|
+
private_class_method :check_date
|
139
|
+
|
140
|
+
# Helper method to validate Luhn algorithm
|
141
|
+
def self.check_luhn(errors, amka)
|
142
|
+
errors << 'AMKA must satisfy the Luhn algorithm check' unless Luhn.safe_valid?(amka)
|
143
|
+
rescue StandardError
|
144
|
+
errors << 'Error checking Luhn algorithm'
|
145
|
+
end
|
146
|
+
private_class_method :check_luhn
|
147
|
+
|
148
|
+
# Strictly validates an AMKA and raises exceptions for invalid input
|
149
|
+
#
|
150
|
+
# Similar to valid? but raises specific exceptions when validation fails,
|
151
|
+
# which is useful for cases where you need detailed error information
|
152
|
+
# or when you prefer exceptions for control flow.
|
153
|
+
#
|
154
|
+
# @param amka [Object] the AMKA to validate
|
155
|
+
# @param year [String, nil] optional four-digit year to match against
|
156
|
+
# @return [true] if the AMKA is valid
|
157
|
+
# @raise [ValidationError] if the AMKA is invalid, with details about why
|
158
|
+
# @example Strict validation with exception handling
|
159
|
+
# begin
|
160
|
+
# Amka.validate!('17019012345') #=> true (if valid)
|
161
|
+
# rescue Amka::ValidationError => e
|
162
|
+
# puts e.message # Contains detailed error info
|
163
|
+
# end
|
164
|
+
def self.validate!(amka, year = nil)
|
165
|
+
errors = validate(amka, year)
|
166
|
+
|
167
|
+
raise ValidationError, errors.first unless errors.empty?
|
168
|
+
|
169
|
+
true
|
58
170
|
end
|
59
171
|
|
60
172
|
# Generates a random valid AMKA
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ioannis Angelakopoulos
|
@@ -35,6 +35,7 @@ metadata:
|
|
35
35
|
homepage_uri: https://github.com/ioagel/amka
|
36
36
|
source_code_uri: https://github.com/ioagel/amka
|
37
37
|
changelog_uri: https://github.com/ioagel/amka/blob/master/CHANGELOG.md
|
38
|
+
documentation_uri: http://rubydoc.info/gems/amka
|
38
39
|
rubygems_mfa_required: 'true'
|
39
40
|
post_install_message:
|
40
41
|
rdoc_options: []
|