Added support for domain names in host_address validator

This commit is contained in:
Maxim Kulkin 2013-09-19 16:09:13 +04:00
parent fac0eb8eba
commit 5aeee0fd69
2 changed files with 75 additions and 1 deletions

View File

@ -251,10 +251,51 @@ def validate_ipv4_network(s):
return '%s/%d' % (address, prefix)
def validate_host_label(s):
if len(s) == 0:
return InvalidValueError('Host label should have at least one character')
if not s[0].isalpha():
return InvalidValueError('Host label should start with a letter, but it starts with "%s"' % s[0])
if len(s) == 1: return s
if not (s[-1].isdigit() or s[-1].isalpha()):
return InvalidValueError('Host label should end with letter or digit, but it ends with "%s"' % s[-1], Mark('', 0, len(s)-1))
if len(s) == 2: return s
for i, c in enumerate(s[1:-1]):
if not (c.isalpha() or c.isdigit() or c == '-'):
return InvalidValueError('Host label should contain only letters, digits or hypens, but it contains "%s"' % c, Mark('', 0, i+1))
return s
@type_validator('host')
@type_validator('host_address')
def validate_host_address(s):
return validate_ipv4_address(s)
result = validate_ipv4_address(s)
if not isissue(result):
return result
offset = len(s) - len(s.lstrip())
parts = s.strip().split('.')
part_offset = offset
labels = []
for part in parts:
host_label = validate_host_label(part)
if isissue(host_label):
return host_label.offset_by(Mark('', 0, part_offset))
part_offset += len(part)+1
labels.append(host_label)
return '.'.join(labels)
@type_validator('network')
@type_validator('network_address')
def validate_network_address(s):
return validate_ipv4_network(s)

View File

@ -93,6 +93,39 @@ class HostAddressTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase):
def test_ipv4_like_string_with_numbers_greater_than_255(self):
self.assertInvalid('10.0.256.1')
def test_host_name(self):
self.assertValid('foo.bar.baz')
def test_host_with_empty_parts(self):
self.assertInvalid('.foo.bar')
self.assertInvalid('foo..bar')
self.assertInvalid('foo.bar.')
def test_host_parts_with_invalid_chars(self):
self.assertInvalid('foo.ba r.baz')
self.assertInvalid('foo.x_y.bar')
def test_host_with_single_host_label(self):
self.assertValid('foo')
def test_host_part_starting_with_non_letter(self):
self.assertInvalid('123foo')
def test_host_that_ends_with_a_hyphen(self):
self.assertInvalid('foo-')
def test_mark_should_point_to_incorrect_symbol(self):
e = self.validator.validate('')
self.assertEqual(0, e.mark.column)
e = self.validator.validate('123foo')
self.assertEqual(0, e.mark.column)
e = self.validator.validate('foo-')
self.assertEqual(3, e.mark.column)
e = self.validator.validate('foo.bar.-baz')
self.assertEqual(8, e.mark.column)
class NetworkAddressTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase):
type_name = 'network_address'