Serial increment fix (#3863)

* Add extra unit tests

* Fix logic errors when generating groups of serial numbers

* Fixes for unit tests
This commit is contained in:
Oliver 2022-10-27 14:00:18 +11:00 committed by GitHub
parent b13e0c3138
commit cff4d9745b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 12 deletions

View File

@ -629,6 +629,13 @@ def extract_serial_numbers(input_string, expected_quantity: int, starting_value=
def add_serial(serial):
"""Helper function to check for duplicated values"""
serial = serial.strip()
# Ignore blank / emtpy serials
if len(serial) == 0:
return
if serial in serials:
add_error(_("Duplicate serial") + f": {serial}")
else:
@ -645,6 +652,10 @@ def extract_serial_numbers(input_string, expected_quantity: int, starting_value=
return serials
for group in groups:
# Calculate the "remaining" quantity of serial numbers
remaining = expected_quantity - len(serials)
group = group.strip()
if '-' in group:
@ -680,20 +691,21 @@ def extract_serial_numbers(input_string, expected_quantity: int, starting_value=
group_items.append(b)
break
elif count > expected_quantity:
elif count > remaining:
# More than the allowed number of items
break
elif a_next is None:
break
if len(group_items) > 0 and group_items[0] == a and group_items[-1] == b:
if len(group_items) > remaining:
add_error(_("Group range {g} exceeds allowed quantity ({q})".format(g=group, q=expected_quantity)))
elif len(group_items) > 0 and group_items[0] == a and group_items[-1] == b:
# In this case, the range extraction looks like it has worked
for item in group_items:
add_serial(item)
else:
add_serial(group)
# add_error(_("Invalid group range: {g}").format(g=group))
add_error(_("Invalid group range: {g}").format(g=group))
else:
# In the case of a different number of hyphens, simply add the entire group
@ -715,7 +727,7 @@ def extract_serial_numbers(input_string, expected_quantity: int, starting_value=
continue
elif len(items) == 2:
try:
if items[1] not in ['', None]:
if items[1]:
sequence_count = int(items[1]) + 1
except ValueError:
add_error(_("Invalid group sequence: {g}").format(g=group))
@ -745,7 +757,7 @@ def extract_serial_numbers(input_string, expected_quantity: int, starting_value=
if len(serials) == 0:
raise ValidationError([_("No serial numbers found")])
if len(serials) != expected_quantity:
if len(errors) == 0 and len(serials) != expected_quantity:
raise ValidationError([_("Number of unique serial numbers ({s}) must match quantity ({q})").format(s=len(serials), q=expected_quantity)])
return serials

View File

@ -447,11 +447,15 @@ class TestSerialNumberExtraction(TestCase):
"""Test simple serial numbers."""
e = helpers.extract_serial_numbers
# Test a range of numbers
sn = e("1-5", 5, 1)
self.assertEqual(len(sn), 5, 1)
self.assertEqual(len(sn), 5)
for i in range(1, 6):
self.assertIn(str(i), sn)
sn = e("11-30", 20, 1)
self.assertEqual(len(sn), 20)
sn = e("1, 2, 3, 4, 5", 5, 1)
self.assertEqual(len(sn), 5)
@ -470,11 +474,6 @@ class TestSerialNumberExtraction(TestCase):
self.assertEqual(len(sn), 5)
self.assertEqual(sn, ['1', '2', "TG-4SR-92", '4', '5'])
# Test groups are not interpolated with alpha characters
sn = e("1, A-2, 3+", 5, 1)
self.assertEqual(len(sn), 5)
self.assertEqual(sn, ['1', "A-2", '3', '4', '5'])
# Test multiple placeholders
sn = e("1 2 ~ ~ ~", 5, 2)
self.assertEqual(len(sn), 5)
@ -539,6 +538,16 @@ class TestSerialNumberExtraction(TestCase):
with self.assertRaises(ValidationError):
e("1, 2, 3, E-5", 5, 1)
# Extract a range of values with a smaller range
with self.assertRaises(ValidationError) as exc:
e("11-50", 10, 1)
self.assertIn('Range quantity exceeds 10', str(exc))
# Test groups are not interpolated with alpha characters
with self.assertRaises(ValidationError) as exc:
e("1, A-2, 3+", 5, 1)
self.assertIn('Invalid group range: A-2', str(exc))
def test_combinations(self):
"""Test complex serial number combinations."""
e = helpers.extract_serial_numbers
@ -559,6 +568,24 @@ class TestSerialNumberExtraction(TestCase):
self.assertEqual(len(sn), 2)
self.assertEqual(sn, ['14', '15'])
# Test multiple increment groups
sn = e("~+4, 20+4, 30+4", 15, 10)
self.assertEqual(len(sn), 15)
for v in [14, 24, 34]:
self.assertIn(str(v), sn)
# Test multiple range groups
sn = e("11-20, 41-50, 91-100", 30, 1)
self.assertEqual(len(sn), 30)
for v in range(11, 21):
self.assertIn(str(v), sn)
for v in range(41, 51):
self.assertIn(str(v), sn)
for v in range(91, 101):
self.assertIn(str(v), sn)
class TestVersionNumber(TestCase):
"""Unit tests for version number functions."""