Skip to content

Commit 13449dc

Browse files
feat: Add ean_number validation to array_validator
1 parent f9001ea commit 13449dc

File tree

10 files changed

+80
-51
lines changed

10 files changed

+80
-51
lines changed

.readthedocs.yaml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,16 @@ build:
99
os: ubuntu-22.04
1010
tools:
1111
python: "3.12"
12-
# You can also specify other tool versions:
13-
# nodejs: "20"
14-
# rust: "1.70"
15-
# golang: "1.20"
1612

1713
# Build documentation in the "docs/" directory with Sphinx
1814
sphinx:
1915
configuration: docs/conf.py
20-
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
21-
# builder: "dirhtml"
22-
# Fail on all warnings to avoid broken references
23-
# fail_on_warning: true
2416

2517
# Optionally build your docs in additional formats such as PDF and ePub
2618
formats:
2719
- pdf
2820
- epub
2921

30-
# Optional but recommended, declare the Python requirements required
31-
# to build your documentation
32-
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
3322
python:
3423
install:
3524
- requirements: docs/requirements.txt

docs/research/ean_number.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@ How to Validate an EAN Code
1717

1818
1. EAN numbers are 13 digits long! If the number is less than 13 digits, it's not a valid EAN code.
1919
2. Add the odd-numbered digits together.
20-
3. multiply the even numbers by 3 and add them together.
20+
3. multiply the odd numbers by 3 and add the even numbers together.
2121
4. divide the sum by 10. If the remainder is 0, the check digit is 0. Otherwise, subtract the remainder from 10 to get the check digit.
2222
5. If the check digit is the same as the last digit of the EAN number, the EAN number is valid.
23+
24+
Example
25+
-------
26+
27+
Ean Number: 8901030679216
28+
29+
1. The last digit is the check digit, so we ignore it for now.
30+
2. Add the odd-numbered digits together: 8 + 0 + 0 + 0 + 7 + 2 = 17
31+
3. add the even numbers together: 9 + 1+ 3+ 6 + 9 + 1 = 29
32+
4. even numbers * 3 + odd numbers = 29 * 3 + 17 = 104
33+
5. 104 % 10 = 4
34+
6. 10 - 4 = 6
35+
7. 6 == 6, so the EAN number is valid.

docs/research/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ Research for the project
1212
license_plate.rst
1313
mobile_number.rst
1414
pan_card.rst
15-
passport.rst
15+
passport.rst
16+
ean_number.rst

sanatio/array_validator.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,26 @@ class ArrayValidator:
22
def __init__(self) -> None:
33
pass
44

5-
def isArray(self, value) -> bool: # TODO: test cases is pending
5+
def isArray(self, value) -> bool:
66
""" check if the string is array or not """
77
if isinstance(value, list):
88
return True
99
return False
1010

11-
def isLength(self, value, min: int=0, max: int=None) -> bool: # TODO: test cases is pending
11+
def isLength(self, value, min: int=0, max: int=None) -> bool:
1212
""" check if the array length is between min and max """
1313
if min <= len(value) <= max:
1414
return True
1515
return False
1616

17-
def isContains(self, value, element) -> bool: # TODO: test cases is pending
17+
def isContains(self, value, element) -> bool:
1818
""" check if the array contains the element or not """
1919
if element in value:
2020
return True
2121
return False
22+
23+
def isUnique(self, value) -> bool:
24+
""" check if the array contains unique elements or not """
25+
if len(value) == len(set(value)):
26+
return True
27+
return False

sanatio/password_validator.py

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class PasswordValidator:
44
def __init__(self):
55
super().__init__()
66

7-
def isStrongPassword(self, value: str) -> bool:
7+
def isStrongPassword(self, value: str, min_length: int=8, special_chars: bool= True, numbers: bool= True, uppercase: bool= True, lowercase: bool= True) -> bool:
88
""" check if the string is strong password or not
99
1010
requirements:
@@ -14,52 +14,42 @@ def isStrongPassword(self, value: str) -> bool:
1414
4. At least one number
1515
5. At least one special character
1616
"""
17-
if len(value) < 8:
17+
if not self.isPasswordLength(value, min_length) or \
18+
(special_chars and not re.search("[_@$]", value)) or \
19+
(numbers and not re.search("[0-9]", value)) or \
20+
(uppercase and not re.search("[A-Z]", value)) or \
21+
(lowercase and not re.search("[a-z]", value)):
1822
return False
19-
20-
if not re.search("[a-z]", value):
21-
return False
22-
23-
if not re.search("[A-Z]", value):
24-
return False
25-
26-
if not re.search("[0-9]", value):
27-
return False
28-
29-
if not re.search("[_@$]", value):
30-
return False
31-
23+
3224
return True
33-
34-
def isPasswordLength(self, value: str, min_length: int, max_length: int) -> bool:
25+
26+
def isPasswordLength(self, value: str, min_length: int) -> bool:
3527
""" check if the string length is between min and max """
36-
if min_length <= len(value) <= max_length:
28+
if len(value) >= min_length:
3729
return True
38-
39-
return False
4030

41-
def isPasswordMatch(self, value: str, match_value: str) -> bool:
31+
def isPasswordMatch(self, value: str, match_value: str, ignore_case: bool=False) -> bool:
4232
""" check if the string matches the match_value """
4333
if value == match_value:
4434
return True
4535

4636
return False
4737

48-
def isPasswordNotMatch(self, value: str, match_value: str) -> bool:
38+
def isPasswordNotMatch(self, value: str, match_value: str, ignore_case: bool=False) -> bool:
4939
""" check if the string does not match the match_value """
5040
if value != match_value:
5141
return True
5242

5343
return False
5444

55-
def isPasswordNotInList(self, value: str, list_values: list) -> bool:
45+
def isPasswordNotInList(self, value: str, list_values: list, ignore_case: bool=False) -> bool:
5646
""" check if the string is not in the list """
5747
if value not in list_values:
5848
return True
5949

6050
return False
6151

62-
def isPasswordNotInFile(self, value: str, file_path: str) -> bool:
52+
def isPasswordNotInFile(self, value: str, file_path: str, ignore_case: bool=False) -> bool:
6353
""" check if the string is not in the file """
6454
with open(file_path, 'r') as f:
6555
data = f.read().splitlines()
@@ -69,7 +59,7 @@ def isPasswordNotInFile(self, value: str, file_path: str) -> bool:
6959

7060
return False
7161

72-
def isPasswordNotInDict(self, value: str, dict_values: dict) -> bool:
62+
def isPasswordNotInDict(self, value: str, dict_values: dict, ignore_case: bool=False) -> bool:
7363
""" check if the string is not in the dictionary """
7464
if value not in dict_values:
7565
return True

sanatio/string_validator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def edit_distance(self, value1, value2):
105105

106106
return difference
107107

108-
def equals(self, value1: str, value2: str, ignoreCase: bool=False)-> bool:
108+
def is_equals(self, value1: str, value2: str, ignoreCase: bool=False)-> bool:
109109
""" Check if the two string are equal or not """
110110
if not self.isvalidString(value1) or not self.isvalidString(value2):
111111
return False

tests/array_test.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,17 @@ def test_isContains_False(self):
3434
self.assertFalse(validator.isContains([1, 2, 3], 4))
3535
self.assertFalse(validator.isContains([1, 2, 3], 5))
3636
self.assertFalse(validator.isContains([1, 2, 3], 6))
37+
38+
def test_isUnique_True(self):
39+
self.assertTrue(validator.isUnique([1, 2, 3]))
40+
self.assertTrue(validator.isUnique(['a', 'b', 'c']))
41+
self.assertTrue(validator.isUnique([1, 'a', 3]))
42+
43+
def test_isUnique_False(self):
44+
self.assertFalse(validator.isUnique([1, 2, 2]))
45+
self.assertFalse(validator.isUnique(['a', 'b', 'b']))
46+
self.assertFalse(validator.isUnique([1, 'a', 3, 3]))
3747

3848

3949
if __name__ == '__main__':
40-
unittest.main()
50+
unittest.main()

tests/ean_test.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11

22
import sys
3+
import random
34
import unittest
45
sys.path.append('.')
56
from sanatio import Validator
67
validator = Validator()
78

9+
def generate_ean13_number():
10+
""" generate ean13 number """
11+
ean_number = ''.join(random.choices('0123456789', k=12))
12+
total_sum = sum(int(ean_number[i]) * 3 if i % 2 != 0 else \
13+
int(ean_number[i]) for i in range(len(ean_number)))
14+
unit_digit = 0 if total_sum % 10 == 0 else 10 - (total_sum % 10)
15+
return ean_number + str(unit_digit)
816

917
class EANTest(unittest.TestCase):
1018
def test_isEAN_true(self):
11-
self.assertTrue(validator.isEAN13('8901030679216'))
12-
self.assertTrue(validator.isEAN13('0067238891190'))
13-
self.assertTrue(validator.isEAN13('6921815600015'))
19+
self.assertTrue(validator.isEAN13(generate_ean13_number()))
20+
self.assertTrue(validator.isEAN13(generate_ean13_number()))
21+
self.assertTrue(validator.isEAN13(generate_ean13_number()))
22+
self.assertTrue(validator.isEAN13(generate_ean13_number()))
23+
self.assertTrue(validator.isEAN13(generate_ean13_number()))
24+
self.assertTrue(validator.isEAN13(generate_ean13_number()))
1425

1526
def test_isEAN_false(self):
1627
self.assertFalse(validator.isEAN13('890103067921'))

tests/password_test.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,21 @@ def test_strong_password_true(self):
1212
self.assertTrue(validator.isStrongPassword('Bar@1234'))
1313
self.assertTrue(validator.isStrongPassword('FooBar@1234'))
1414
self.assertTrue(validator.isStrongPassword('FooBar@1234'))
15+
self.assertTrue(validator.isStrongPassword('FooBar1234', special_chars=False))
16+
self.assertTrue(validator.isStrongPassword('foobar@1234', uppercase=False))
17+
self.assertTrue(validator.isStrongPassword('1234', min_length=4,
18+
uppercase=False,
19+
lowercase=False,
20+
special_chars=False))
21+
1522

1623
def test_strong_password_false(self):
1724
self.assertFalse(validator.isStrongPassword('foo'))
1825
self.assertFalse(validator.isStrongPassword('foo123'))
1926
self.assertFalse(validator.isStrongPassword('foo@123'))
2027
self.assertFalse(validator.isStrongPassword('FOO@123'))
28+
self.assertFalse(validator.isStrongPassword('Foo@1234', min_length=13))
29+
2130

2231

2332
if __name__ == '__main__':

tests/string_case_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ class ValidatorTest(unittest.TestCase):
1010
""" """
1111

1212
def test_equals_true(self):
13-
self.assertTrue(validator.equals('foo', 'foo'))
14-
self.assertTrue(validator.equals('foo', 'Foo', ignoreCase=True))
13+
self.assertTrue(validator.is_equals('foo', 'foo'))
14+
self.assertTrue(validator.is_equals('foo', 'Foo', ignoreCase=True))
1515

1616
def test_equals_false(self):
17-
self.assertFalse(validator.equals('foo', 'bar'))
18-
self.assertFalse(validator.equals('foo', 'Foo'))
19-
self.assertFalse(validator.equals('foo', 'Foo', ignoreCase=False))
17+
self.assertFalse(validator.is_equals('foo', 'bar'))
18+
self.assertFalse(validator.is_equals('foo', 'Foo'))
19+
self.assertFalse(validator.is_equals('foo', 'Foo', ignoreCase=False))
2020

2121
def test_length_true(self):
2222
self.assertTrue(validator.isLength('foo', 1, 3))

0 commit comments

Comments
 (0)