def test_can_validate_python_name(self): self.assertEqual(_tools.validated_python_name("x", "abc_123"), "abc_123") self.assertEqual(_tools.validated_python_name("x", " abc_123 "), "abc_123") self.assertRaises(NameError, _tools.validated_python_name, "x", "1337") self.assertRaises(NameError, _tools.validated_python_name, "x", "") self.assertRaises(NameError, _tools.validated_python_name, "x", " ") self.assertRaises(NameError, _tools.validated_python_name, "x", "a.b")
def test_can_validate_python_name(self): self.assertEqual(_tools.validated_python_name('x', 'abc_123'), 'abc_123') self.assertEqual(_tools.validated_python_name('x', ' abc_123 '), 'abc_123') self.assertRaises(NameError, _tools.validated_python_name, 'x', '1337') self.assertRaises(NameError, _tools.validated_python_name, 'x', '') self.assertRaises(NameError, _tools.validated_python_name, 'x', ' ') self.assertRaises(NameError, _tools.validated_python_name, 'x', 'a.b')
def add_field_format_row(self, possibly_incomplete_items): """ Add field as described by `possibly_incomplete_items`, which is a list consisting of: 1) field name 2) optional: example value (can be empty) 3) optional: empty flag ("X" = field is allowed to be empty) 4) optional: length (using the syntax of :py:class:`cutplace.ranges.Range`) 5) optional: field type (e.g. 'Integer' for :py:class:`cutplace.fields.IntegerFieldFormat`) 6) optional: rule to validate field (depending on type) Any missing items are interpreted as empty string (``''``). Additional items are ignored. :raises cutplace.errors.InterfaceError: on broken \ ``possibly_incomplete_items`` """ assert possibly_incomplete_items is not None assert self._location is not None if self._data_format is None: raise errors.InterfaceError( "data format must be specified before first field", self._location) # Assert that the various lists and maps related to fields are in a consistent state. # Ideally this would be a class invariant, but this is Python, not Eiffel. field_count = len(self.field_names) assert len(self._field_formats) == field_count assert len(self._field_name_to_format_map) == field_count assert len(self._field_name_to_index_map) == field_count items = (possibly_incomplete_items + 6 * [''])[:6] # Obtain field name. field_name = fields.validated_field_name(items[0], self._location) if field_name in self._field_name_to_format_map: # TODO: Add see_also_location pointing to previous declaration. raise errors.InterfaceError( 'duplicate field name must be changed to a unique one: %s' % field_name, self._location) # Obtain example. self._location.advance_cell() field_example = items[1] # Obtain "empty" mark. self._location.advance_cell() field_is_allowed_to_be_empty_text = items[2].strip().lower() if field_is_allowed_to_be_empty_text == '': field_is_allowed_to_be_empty = False elif field_is_allowed_to_be_empty_text == self._EMPTY_INDICATOR: field_is_allowed_to_be_empty = True else: raise errors.InterfaceError( "mark for empty field must be %s or empty but is %s" % (self._EMPTY_INDICATOR, field_is_allowed_to_be_empty_text), self._location) # Obtain length. self._location.advance_cell() field_length = items[3] # Obtain field type and rule. self._location.advance_cell() field_type_item = items[4].strip() if field_type_item == '': field_type = 'Text' else: field_type = '' field_type_parts = field_type_item.split(".") try: for part in field_type_parts: if field_type: field_type += "." field_type += _tools.validated_python_name( "field type part", part) assert field_type, "empty field type must be detected by validated_python_name()" except NameError as error: raise errors.InterfaceError(six.text_type(error), self._location) field_class = self._create_field_format_class(field_type) self._location.advance_cell() field_rule = items[5].strip() _log.debug("create field: %s(%r, %r, %r)", field_class.__name__, field_name, field_type, field_rule) try: field_format = field_class.__new__(field_class, field_name, field_is_allowed_to_be_empty, field_length, field_rule) field_format.__init__(field_name, field_is_allowed_to_be_empty, field_length, field_rule, self._data_format) except errors.InterfaceError as error: error_location = error.location if error.location is not None else self._location error.prepend_message( 'cannot declare field %s' % _compat.text_repr(field_name), error_location) raise error # Validate field length. # TODO #82: Cleanup validation for declared field formats. self._location.set_cell(4) field_length = field_format.length if self._data_format.format == data.FORMAT_FIXED: if field_length.items is None: raise errors.InterfaceError( "length of field %s must be specified with fixed data format" % _compat.text_repr(field_name), self._location) if field_length.lower_limit != field_length.upper_limit: raise errors.InterfaceError( "length of field %s for fixed data format must be a specific number but is: %s" % (_compat.text_repr(field_name), field_format.length), self._location) if field_length.lower_limit < 1: raise errors.InterfaceError( "length of field %s for fixed data format must be at least 1 but is: %d" % (_compat.text_repr(field_name), field_format.length.lower_limit), self._location) elif field_length.lower_limit is not None: if field_length.lower_limit < 0: raise errors.InterfaceError( "lower limit for length of field %s must be at least 0 but is: %d" % (_compat.text_repr(field_name), field_format.length.lower_limit), self._location) elif field_length.upper_limit is not None: # Note: 0 as upper limit is valid for a field that must always be empty. if field_length.upper_limit < 0: raise errors.InterfaceError( "upper limit for length of field %s must be at least 0 but is: %d" % (_compat.text_repr(field_name), field_format.length.upper_limit), self._location) # Set and validate example in case there is one. if field_example != '': try: field_format.example = field_example except errors.FieldValueError as error: self._location.set_cell(2) raise errors.InterfaceError( "cannot validate example for field %s: %s" % (_compat.text_repr(field_name), error), self._location) self._location.set_cell(1) assert field_name assert field_type assert field_rule is not None self.add_field_format(field_format)
def add_field_format_row(self, possibly_incomplete_items): """ Add field as described by `possibly_incomplete_items`, which is a list consisting of: 1) field name 2) optional: example value (can be empty) 3) optional: empty flag ("X" = field is allowed to be empty) 4) optional: length (using the syntax of :py:class:`cutplace.ranges.Range`) 5) optional: field type (e.g. 'Integer' for :py:class:`cutplace.fields.IntegerFieldFormat`) 6) optional: rule to validate field (depending on type) Any missing items are interpreted as empty string (``''``). Additional items are ignored. :raises cutplace.errors.InterfaceError: on broken \ ``possibly_incomplete_items`` """ assert possibly_incomplete_items is not None assert self._location is not None if self._data_format is None: raise errors.InterfaceError("data format must be specified before first field", self._location) # Assert that the various lists and maps related to fields are in a consistent state. # Ideally this would be a class invariant, but this is Python, not Eiffel. field_count = len(self.field_names) assert len(self._field_formats) == field_count assert len(self._field_name_to_format_map) == field_count assert len(self._field_name_to_index_map) == field_count items = (possibly_incomplete_items + 6 * [''])[:6] # Obtain field name. field_name = fields.validated_field_name(items[0], self._location) if field_name in self._field_name_to_format_map: # TODO: Add see_also_location pointing to previous declaration. raise errors.InterfaceError( 'duplicate field name must be changed to a unique one: %s' % field_name, self._location) # Obtain example. self._location.advance_cell() field_example = items[1] # Obtain "empty" mark. self._location.advance_cell() field_is_allowed_to_be_empty_text = items[2].strip().lower() if field_is_allowed_to_be_empty_text == '': field_is_allowed_to_be_empty = False elif field_is_allowed_to_be_empty_text == self._EMPTY_INDICATOR: field_is_allowed_to_be_empty = True else: raise errors.InterfaceError( "mark for empty field must be %s or empty but is %s" % (self._EMPTY_INDICATOR, field_is_allowed_to_be_empty_text), self._location) # Obtain length. self._location.advance_cell() field_length = items[3] # Obtain field type and rule. self._location.advance_cell() field_type_item = items[4].strip() if field_type_item == '': field_type = 'Text' else: field_type = '' field_type_parts = field_type_item.split(".") try: for part in field_type_parts: if field_type: field_type += "." field_type += _tools.validated_python_name("field type part", part) assert field_type, "empty field type must be detected by validated_python_name()" except NameError as error: raise errors.InterfaceError(six.text_type(error), self._location) field_class = self._create_field_format_class(field_type) self._location.advance_cell() field_rule = items[5].strip() _log.debug("create field: %s(%r, %r, %r)", field_class.__name__, field_name, field_type, field_rule) try: field_format = field_class.__new__( field_class, field_name, field_is_allowed_to_be_empty, field_length, field_rule) field_format.__init__( field_name, field_is_allowed_to_be_empty, field_length, field_rule, self._data_format) except errors.InterfaceError as error: error_location = error.location if error.location is not None else self._location error.prepend_message('cannot declare field %s' % _compat.text_repr(field_name), error_location) raise error # Validate field length. # TODO #82: Cleanup validation for declared field formats. self._location.set_cell(4) field_length = field_format.length if self._data_format.format == data.FORMAT_FIXED: if field_length.items is None: raise errors.InterfaceError( "length of field %s must be specified with fixed data format" % _compat.text_repr(field_name), self._location) if field_length.lower_limit != field_length.upper_limit: raise errors.InterfaceError( "length of field %s for fixed data format must be a specific number but is: %s" % (_compat.text_repr(field_name), field_format.length), self._location) if field_length.lower_limit < 1: raise errors.InterfaceError( "length of field %s for fixed data format must be at least 1 but is: %d" % (_compat.text_repr(field_name), field_format.length.lower_limit), self._location) elif field_length.lower_limit is not None: if field_length.lower_limit < 0: raise errors.InterfaceError( "lower limit for length of field %s must be at least 0 but is: %d" % (_compat.text_repr(field_name), field_format.length.lower_limit), self._location) elif field_length.upper_limit is not None: # Note: 0 as upper limit is valid for a field that must always be empty. if field_length.upper_limit < 0: raise errors.InterfaceError( "upper limit for length of field %s must be at least 0 but is: %d" % (_compat.text_repr(field_name), field_format.length.upper_limit), self._location) # Set and validate example in case there is one. if field_example != '': try: field_format.example = field_example except errors.FieldValueError as error: self._location.set_cell(2) raise errors.InterfaceError( "cannot validate example for field %s: %s" % (_compat.text_repr(field_name), error), self._location) self._location.set_cell(1) assert field_name assert field_type assert field_rule is not None self.add_field_format(field_format)