def test_assign_wrong_subcomponent_to_known_position(self): c = Component('XPN_1') with self.assertRaises(ChildNotValid): c.fn_1 = SubComponent('hd_1') c1 = Component('XPN_1', validation_level=VALIDATION_LEVEL.STRICT) with self.assertRaises(ChildNotValid): c1.fn_1 = SubComponent('hd_1')
def test_override_datatype_strict(self): c = Component('CX_1', validation_level=VALIDATION_LEVEL.STRICT) with self.assertRaises(OperationNotAllowed): c.datatype = 'TX' c1 = Component('CX_1', datatype='ST', validation_level=VALIDATION_LEVEL.STRICT) with self.assertRaises(OperationNotAllowed): c1.datatype = 'TX'
def test_wrong_datatype_component(self): """ Tests that if a component is not of the correct datatype the message is not validate The message used has the MSG_1 of type ST """ msg = self._create_message(self.adt_a01) msg_1 = Component('MSG_1', datatype='ST') msg_1.add(SubComponent(datatype='ST', value='ADT_A01')) msg.msh.msh_9.msg_1 = msg_1 self.assertFalse(msg.validate())
def test_wrong_datatype_component(self): """ Tests that if a component is not of the correct datatype the message is not validate The message used has the MSG_1 of type ST """ msg = self._create_message(self.rsp_k21) msg_1 = Component('MSG_1', datatype='ST') msg_1.add(SubComponent(datatype='ST', value='ADT_A01')) msg.msh.msh_9.msg_1 = msg_1 self.assertRaises(ValidationError, msg.validate, report_file=self.report_file) self._test_report_file('ERROR')
def test_assign_value_traversal(self): subcmp_str = 'xxx' c1 = Component('CX_10') c2 = Component('CX_10') c1.cwe_1 = subcmp_str c2.cwe_1.value = subcmp_str self.assertEqual(c1.to_er7(), c2.to_er7()) s1 = Segment('PID') s2 = Segment('PID') s1.pid_4.pid_4_10_1.value = subcmp_str s2.pid_4.pid_4_10_1 = subcmp_str self.assertEqual(s1.to_er7(), s2.to_er7())
def parse_field(text, name=None, version=None, encoding_chars=None, validation_level=None, reference=None, force_varies=False): """ Parse the given ER7-encoded field and return an instance of :class:`hl7apy.core.Field`. :type text: ``basestring`` :param text: the ER7-encoded string containing the fields to be parsed :type name: ``basestring`` :param name: the field name (e.g. MSH_7) :type version: ``basestring`` :param version: the HL7 version (e.g. "2.5"), or ``None`` to use the default (see :func:`hl7apy.set_default_version`) :type encoding_chars: ``dict`` :param encoding_chars: a dictionary containing the encoding chars or None to use the default (see :func:`hl7apy.set_default_encoding_chars`) :param validation_level: the validation level. Possible values are those defined in :class:`hl7apy.consts.VALIDATION_LEVEL` class or ``None`` to use the default validation level (see :func:`hl7apy.set_default_validation_level`) :type reference: ``dict`` :param reference: a dictionary containing the element structure returned by :func:`hl7apy.load_reference` or :func:`hl7apy.find_reference` :return: an instance of :class:`hl7apy.core.Field` >>> field = "NUCLEAR^NELDA^W" >>> nk1_2 = parse_field(field, name="NK1_2") >>> print nk1_2 <Field NK1_2 (NAME) of type XPN> >>> print nk1_2.to_er7() NUCLEAR^NELDA^W >>> unknown = parse_field(field) >>> print unknown <Field of type None> >>> print unknown.to_er7() NUCLEAR^NELDA^W """ version = _get_version(version) encoding_chars = _get_encoding_chars(encoding_chars) if force_varies: reference = ('leaf', 'varies', None, None) try: field = Field(name, version=version, validation_level=validation_level, reference=reference) except InvalidName: field = Field(version=version, validation_level=validation_level, reference=reference) if name in ('MSH_1', 'MSH_2'): s = SubComponent(datatype='ST', value=text) c = Component(datatype='ST') c.add(s) field.add(c) else: children = parse_components(text, field.datatype, version, encoding_chars, validation_level) if Validator.is_quiet(validation_level) and is_base_datatype(field.datatype, version) and \ len(children) > 1: field.datatype = None field.children = children return field
def test_assign_value_with_component_separator(self): cmp_str = 'xxx^yyy' c = Component() c.value = cmp_str self.assertEqual(c.to_er7(), 'xxx\S\yyy') c = Component('CWE_1') c.value = cmp_str self.assertEqual(c.to_er7(), 'xxx\S\yyy') c = Component('CWE_1', validation_level=VALIDATION_LEVEL.STRICT) c.value = cmp_str self.assertEqual(c.to_er7(), 'xxx\S\yyy')
def test_wrong_component(self): """ Tests that if there is an unexpected component the message in not validated The message used has an unexpected unknown component in the msh_9 """ msg = self._create_message(self.rsp_k21) unkn_component = Component() msg.msh.msh_9.add(unkn_component) self.assertRaises(ValidationError, msg.validate, report_file=self.report_file) self._test_report_file('ERROR')
def parse_component(text, name=None, datatype='ST', version=None, encoding_chars=None, validation_level=None, reference=None): """ Parse the given ER7-encoded component and return an instance of :class:`hl7apy.core.Component`. :type text: ``basestring`` :param text: the ER7-encoded string containing the components to be parsed :type name: ``basestring`` :param name: the component's name (e.g. XPN_2) :type datatype: ``basestring`` :param datatype: the datatype of the component (e.g. ST) :type version: ``basestring`` :param version: the HL7 version (e.g. "2.5"), or ``None`` to use the default (see :func:`hl7apy.set_default_version`) :type encoding_chars: ``dict`` :param encoding_chars: a dictionary containing the encoding chars or None to use the default (see :func:`hl7apy.set_default_encoding_chars`) :param validation_level: the validation level. Possible values are those defined in :class:`hl7apy.consts.VALIDATION_LEVEL` class or ``None`` to use the default validation level (see :func:`hl7apy.set_default_validation_level`) :type reference: ``dict`` :param reference: a dictionary containing the element structure returned by :func:`hl7apy.load_reference` or :func:`hl7apy.find_reference` :return: an instance of :class:`hl7apy.core.Component` >>> component = "GATEWAY&1.3.6.1.4.1.21367.2011.2.5.17" >>> cx_4 = parse_component(component, name="CX_4") >>> print cx_4 <Component CX_4 (ASSIGNING_AUTHORITY) of type None> >>> print cx_4.to_er7() GATEWAY&1.3.6.1.4.1.21367.2011.2.5.17 >>> print parse_component(component) <Component ST (None) of type None> """ version = _get_version(version) encoding_chars = _get_encoding_chars(encoding_chars) try: component = Component(name, datatype, version=version, validation_level=validation_level, reference=reference) except InvalidName as e: if Validator.is_strict(validation_level): raise e component = Component(datatype, version=version, validation_level=validation_level, reference=reference) children = parse_subcomponents(text, component.datatype, version, encoding_chars, validation_level) if Validator.is_quiet(component.validation_level) and is_base_datatype(component.datatype, version) and \ len(children) > 1: component.datatype = None component.children = children return component
def test_wrong_subcomponent(self): """ Tests that if there is an unexpected subcomponent the message in not validated The message used has an unexpected unknown subcomponent in the cx_10 """ msg = self._create_message(self.rsp_k21) unkn_subcomponent = SubComponent(datatype='ST') msg.rsp_k21_query_response.pid.pid_3.cx_10 = Component('CX_10') msg.rsp_k21_query_response.pid.pid_3.cx_10.add(unkn_subcomponent) self.assertRaises(ValidationError, msg.validate, report_file=self.report_file) self._test_report_file('ERROR')
def test_highlights(self): """ It tests the highlighting functionaly """ msg = self._create_test_message(self.msh_values_standard) value = ST('HIGHLIGHTEDTEXTIMPORTANT', highlights=((0,11), (15,24))) s = SubComponent(datatype='ST', value=value) c = Component(datatype='ST') c.add(s) msg.msh.msh_8.msh_8_1 = c self.assertEqual(msg.to_er7(), self.msh_highlighted) value = ST('HIGHLIGHTEDTEXTIMPORTANT', highlights=((15,24), (0,11))) s = SubComponent(datatype='ST', value=value) c = Component(datatype='ST') c.add(s) msg.msh.msh_8.msh_8_1 = c self.assertEqual(msg.to_er7(), self.msh_highlighted)
def test_assign_value_unknown_component(self): cmp_str = 'xxx' complex_cmp_str = 'xxx&&&&yyy' c = Component() c.value = cmp_str c.value = complex_cmp_str
def parse_field(text, name=None, version=None, encoding_chars=None, validation_level=None, reference=None, force_varies=False): """ Parse the given ER7-encoded field and return an instance of :class:`Field <hl7apy.core.Field>`. :type text: ``str`` :param text: the ER7-encoded string containing the fields to be parsed :type name: ``str`` :param name: the field name (e.g. MSH_7) :type version: ``str`` :param version: the HL7 version (e.g. "2.5"), or ``None`` to use the default (see :func:`set_default_version <hl7apy.set_default_version>`) :type encoding_chars: ``dict`` :param encoding_chars: a dictionary containing the encoding chars or None to use the default (see :func:`set_default_encoding_chars <hl7apy.set_default_encoding_chars>`) :type validation_level: ``int`` :param validation_level: the validation level. Possible values are those defined in :class:`VALIDATION_LEVEL <hl7apy.consts.VALIDATION_LEVEL>` class or ``None`` to use the default validation level (see :func:`set_default_validation_level <hl7apy.set_default_validation_level>`) :type reference: ``dict`` :param reference: a dictionary containing the element structure returned by :func:`load_reference <hl7apy.load_reference>` or :func:`find_reference <hl7apy.find_reference>` or belonging to a message profile :type force_varies: ``boolean`` :param force_varies: flag that force the fields to use a varies structure when no reference is found. It is used when a segment ends with a field of type varies that thus support infinite children :return: an instance of :class:`Field <hl7apy.core.Field>` >>> field = "NUCLEAR^NELDA^W" >>> nk1_2 = parse_field(field, name="NK1_2") >>> print(nk1_2) <Field NK1_2 (NAME) of type XPN> >>> print(nk1_2.to_er7()) NUCLEAR^NELDA^W >>> unknown = parse_field(field) >>> print(unknown) <Field of type None> >>> print(unknown.to_er7()) NUCLEAR^NELDA^W """ version = _get_version(version) encoding_chars = _get_encoding_chars(encoding_chars) validation_level = _get_validation_level(validation_level) try: field = Field(name, version=version, validation_level=validation_level, reference=reference) except InvalidName: if force_varies: reference = ('leaf', 'varies', None, None) field = Field(name, version=version, validation_level=validation_level, reference=reference) else: field = Field(version=version, validation_level=validation_level, reference=reference) if name in ('MSH_1', 'MSH_2'): s = SubComponent(datatype='ST', value=text, validation_level=validation_level, version=version) c = Component(datatype='ST', validation_level=validation_level, version=version) c.add(s) field.add(c) else: children = parse_components(text, field.datatype, version, encoding_chars, validation_level, field.structure_by_name) if Validator.is_tolerant(validation_level) and is_base_datatype(field.datatype, version) and \ len(children) > 1: field.datatype = None field.children = children return field
def parse_component(text, name=None, datatype='ST', version=None, encoding_chars=None, validation_level=None, reference=None): """ Parse the given ER7-encoded component and return an instance of :class:`Component <hl7apy.core.Component>`. :type text: ``str`` :param text: the ER7-encoded string containing the components to be parsed :type name: ``str`` :param name: the component's name (e.g. XPN_2) :type datatype: ``str`` :param datatype: the datatype of the component (e.g. ST) :type version: ``str`` :param version: the HL7 version (e.g. "2.5"), or ``None`` to use the default (see :func:`set_default_version <hl7apy.set_default_version>`) :type encoding_chars: ``dict`` :param encoding_chars: a dictionary containing the encoding chars or None to use the default (see :func:`set_default_encoding_chars <hl7apy.set_default_encoding_chars>`) :type validation_level: ``int`` :param validation_level: the validation level. Possible values are those defined in :class:`VALIDATION_LEVEL <hl7apy.consts.VALIDATION_LEVEL>` class or ``None`` to use the default validation level (see :func:`set_default_validation_level <hl7apy.set_default_validation_level>`) :type reference: ``dict`` :param reference: a dictionary containing the element structure returned by :func:`load_reference <hl7apy.load_reference>` or :func:`find_reference <hl7apy.find_reference>` or belonging to a message profile :return: an instance of :class:`Component <hl7apy.core.Component>` >>> component = "GATEWAY&1.3.6.1.4.1.21367.2011.2.5.17" >>> cx_4 = parse_component(component, name="CX_4") >>> print(cx_4) <Component CX_4 (ASSIGNING_AUTHORITY) of type None> >>> print(cx_4.to_er7()) GATEWAY&1.3.6.1.4.1.21367.2011.2.5.17 >>> print(parse_component(component)) <Component ST (None) of type None> """ version = _get_version(version) encoding_chars = _get_encoding_chars(encoding_chars) validation_level = _get_validation_level(validation_level) try: component = Component(name, datatype, version=version, validation_level=validation_level, reference=reference) except InvalidName as e: if Validator.is_strict(validation_level): raise e component = Component(datatype, version=version, validation_level=validation_level, reference=reference) children = parse_subcomponents(text, component.datatype, version, encoding_chars, validation_level) if Validator.is_tolerant(component.validation_level) and is_base_datatype(component.datatype, version) and \ len(children) > 1: component.datatype = None component.children = children return component
def test_add_more_subcomponents_to_base_datatype_component(self): c = Component(datatype='ST') c.add(SubComponent(datatype='ST')) self.assertRaises(MaxChildLimitReached, c.add, SubComponent(datatype='ST'))
def test_add_empty_subcomponent(self): c1 = Component('cx_4', validation_level=VALIDATION_LEVEL.STRICT) self.assertRaises(ChildNotValid, c1.add, SubComponent(datatype='ST')) c2 = Component('cx_4') c2.add(SubComponent(datatype='ST'))
def test_override_valued_datatype(self): c = Component('CX_1') c.datatype = 'TX' self.assertEqual(c.datatype, 'TX')
def parse_field(text, name=None, version=None, encoding_chars=None, validation_level=None, reference=None, force_varies=False): """ Parse the given ER7-encoded field and return an instance of :class:`Field <hl7apy.core.Field>`. :type text: ``str`` :param text: the ER7-encoded string containing the fields to be parsed :type name: ``str`` :param name: the field name (e.g. MSH_7) :type version: ``str`` :param version: the HL7 version (e.g. "2.5"), or ``None`` to use the default (see :func:`set_default_version <hl7apy.set_default_version>`) :type encoding_chars: ``dict`` :param encoding_chars: a dictionary containing the encoding chars or None to use the default (see :func:`set_default_encoding_chars <hl7apy.set_default_encoding_chars>`) :type validation_level: ``int`` :param validation_level: the validation level. Possible values are those defined in :class:`VALIDATION_LEVEL <hl7apy.consts.VALIDATION_LEVEL>` class or ``None`` to use the default validation level (see :func:`set_default_validation_level <hl7apy.set_default_validation_level>`) :type reference: ``dict`` :param reference: a dictionary containing the element structure returned by :func:`load_reference <hl7apy.load_reference>` or :func:`find_reference <hl7apy.find_reference>` or belonging to a message profile :type force_varies: ``boolean`` :param force_varies: flag that force the fields to use a varies structure when no reference is found. It is used when a segment ends with a field of type varies that thus support infinite children :return: an instance of :class:`Field <hl7apy.core.Field>` >>> field = "NUCLEAR^NELDA^W" >>> nk1_2 = parse_field(field, name="NK1_2") >>> print(nk1_2) <Field NK1_2 (NAME) of type XPN> >>> print(nk1_2.to_er7()) NUCLEAR^NELDA^W >>> unknown = parse_field(field) >>> print(unknown) <Field of type None> >>> print(unknown.to_er7()) NUCLEAR^NELDA^W """ version = _get_version(version) encoding_chars = _get_encoding_chars(encoding_chars, version) validation_level = _get_validation_level(validation_level) try: field = Field(name, version=version, validation_level=validation_level, reference=reference) except InvalidName: if force_varies: reference = ('leaf', None, 'varies', None, None, -1) field = Field(name, version=version, validation_level=validation_level, reference=reference) else: field = Field(version=version, validation_level=validation_level, reference=reference) if name in ('MSH_1', 'MSH_2'): s = SubComponent(datatype='ST', value=text, validation_level=validation_level, version=version) c = Component(datatype='ST', validation_level=validation_level, version=version) c.add(s) field.add(c) else: children = parse_components(text, field.datatype, version, encoding_chars, validation_level, field.structure_by_name) if Validator.is_tolerant(validation_level) and is_base_datatype(field.datatype, version) and \ len(children) > 1: field.datatype = None field.children = children return field
def test_add_subcomponent(self): c = Component('XPN_1') c.add_subcomponent('FN_1') self.assertEqual(c.children[0].name, 'FN_1')
def test_assign_value_quiet(self): cmp_str = 'xxx' c = Component('CWE_1') c.value = cmp_str parsed_cmp = parse_component(cmp_str, 'CWE_1') self.assertEqual(c.to_er7(), parsed_cmp.to_er7()) c = Component('CWE_1') # more child than allowed c.value = '1&2' for dt in ('ST', 'ID', 'FT', 'GTS', 'IS', 'TX'): c = Component(datatype=dt) # max length reached string type c.value = 65537*'a' for dt in ('NM', 'SI'): c = Component(datatype=dt) c.value = 65537*'1' complex_cmp_str = 'xxx&yyy&zzz' c = Component('CX_10', validation_level=VALIDATION_LEVEL.QUIET) c.value = complex_cmp_str parsed_cmp = parse_component(complex_cmp_str, 'CX_10', datatype='CWE', validation_level=VALIDATION_LEVEL.STRICT) self.assertEqual(c.to_er7(), parsed_cmp.to_er7())
def test_assign_value_strict(self): cmp_str = 'xxx' c = Component('CWE_1', validation_level=VALIDATION_LEVEL.STRICT) c.value = cmp_str parsed_cmp = parse_component(cmp_str, 'CWE_1') self.assertEqual(c.to_er7(), parsed_cmp.to_er7()) c = Component('CWE_1', validation_level=VALIDATION_LEVEL.STRICT) with self.assertRaises(MaxChildLimitReached): c.value = '1&2' with self.assertRaises(MaxLengthReached): for dt in ('ST', 'ID', 'FT', 'GTS', 'IS', 'TX'): c = Component(datatype=dt, validation_level=VALIDATION_LEVEL.STRICT) # max length reached string type c.value = 65537*'a' for dt in ('NM', 'SI'): c = Component(datatype=dt, validation_level=VALIDATION_LEVEL.STRICT) c.value = int(65537*'1') complex_cmp_str = 'xxx&yyy&zzz' c = Component('CX_10', validation_level=VALIDATION_LEVEL.STRICT) c.value = complex_cmp_str parsed_cmp = parse_component(complex_cmp_str, 'CX_10', datatype='CWE', validation_level=VALIDATION_LEVEL.STRICT) self.assertEqual(c.to_er7(), parsed_cmp.to_er7())