def test_register_all(self): factory = Factory() classes = {"test-a": TestClassA, "test-b": TestClassB} factory.register_all(classes) self.assertIsInstance(factory.create("test-a"), TestClassA) self.assertIsInstance(factory.create("test-b"), TestClassB)
def test_register_all(self): factory = Factory() classes = { "test-a": TestClassA, "test-b": TestClassB } factory.register_all(classes) self.assertIsInstance(factory.create("test-a"), TestClassA) self.assertIsInstance(factory.create("test-b"), TestClassB)
class SchemaParser(AbstractSchemaParser): """SchemaParser class Implements the inteface defined in the AbstractSchemaParser class """ def __init__(self, schema): """Initialise the parser with the schema :param schema: the schema json object or dict """ self._version = "0.0.1" self._schema = schema self.answer_factory = Factory() self.answer_factory.register_all({ 'CHECKBOX': CheckboxAnswer, 'CURRENCY': CurrencyAnswer, 'DATE': DateAnswer, 'MONTHYEARDATE': MonthYearDateAnswer, 'INTEGER': IntegerAnswer, 'PERCENTAGE': PercentageAnswer, 'POSITIVEINTEGER': PositiveIntegerAnswer, 'RADIO': RadioAnswer, 'TEXTAREA': TextareaAnswer, 'TEXTFIELD': TextfieldAnswer, 'RELATIONSHIP': RelationshipAnswer, }) self.question_factory = Factory() self.question_factory.register_all({ 'GENERAL': GeneralQuestion, 'DATERANGE': DateRangeQuestion, 'REPEATINGANSWER': RepeatingAnswerQuestion, 'RELATIONSHIP': RelationshipQuestion, }) def get_parser_version(self): """Return which version of the parser :returns: The version number as a string, e.g. "0.0.1" """ return self._version def parse(self): """Parse the schema :returns: A questionnaire object :raises: A SchemaParserException if there is a problem while parsing the schema """ questionnaire = Questionnaire() questionnaire.id = ParserUtils.get_required_string( self._schema, "questionnaire_id") questionnaire.title = ParserUtils.get_required_string( self._schema, "title") questionnaire.survey_id = ParserUtils.get_required_string( self._schema, "survey_id") logger.debug("title: " + questionnaire.title) questionnaire.description = ParserUtils.get_optional_string( self._schema, "description") questionnaire.theme = ParserUtils.get_required_string( self._schema, "theme") questionnaire.data_version = ParserUtils.get_required_string( self._schema, "data_version") if "introduction" in self._schema.keys(): questionnaire.introduction = self._parse_introduction( self._schema['introduction']) if "groups" in self._schema.keys(): for group_schema in self._schema['groups']: questionnaire.add_group( self._parse_group(group_schema, questionnaire)) else: raise SchemaParserException( 'Questionnaire must contain at least one group') if 'messages' in self._schema.keys(): # re-use the parse validation method self._parse_validation(questionnaire, self._schema) questionnaire.register_aliases() return questionnaire @staticmethod def _parse_introduction(intro_schema): introduction = Introduction() introduction.legal = ParserUtils.get_optional_string( intro_schema, 'legal') introduction.description = ParserUtils.get_optional_string( intro_schema, 'description') introduction.information_to_provide = ParserUtils.get_optional_array( intro_schema, 'information_to_provide') return introduction def _parse_group(self, schema, questionnaire): """Parse a group element :param schema: The group schema :returns: Group object :raises: SchemaParserException """ group = Group() group.id = ParserUtils.get_required_string(schema, "id") group.title = ParserUtils.get_optional_string(schema, "title") # Register the group questionnaire.register(group) if "blocks" in schema.keys(): for block_schema in schema['blocks']: group.add_block(self._parse_block(block_schema, questionnaire)) else: raise SchemaParserException( 'Group must contain at least one block') return group def _parse_block(self, schema, questionnaire): """Parse a block element :param schema: The block schema :returns: A Block object :raises: SchemaParserException """ block = Block() block.id = ParserUtils.get_required_string(schema, "id") block.title = ParserUtils.get_optional_string(schema, "title") block.type = ParserUtils.get_optional_string(schema, "type") # register the block questionnaire.register(block) if "sections" in schema.keys(): for section_schema in schema['sections']: block.add_section( self._parse_section(section_schema, questionnaire)) else: raise SchemaParserException( 'Block must contain at least one section') return block def _parse_section(self, schema, questionnaire): """Parse a section element :param schema: The section schema :returns: A Section object :raises: SchemaParserException """ section = Section() section.id = ParserUtils.get_required_string(schema, "id") section.title = ParserUtils.get_optional_string(schema, "title") section.number = ParserUtils.get_optional_string(schema, "number") section.description = ParserUtils.get_optional_string( schema, "description") questionnaire.register(section) if 'questions' in schema.keys(): for question_schema in schema['questions']: section.add_question( self._parse_question(question_schema, questionnaire)) else: raise SchemaParserException( 'Section must have at least one question') return section def _parse_question(self, schema, questionnaire): """Parse a question element :param schema: The question schema :returns: A Question object :raises: SchemaParserException """ question_type = ParserUtils.get_required_string(schema, "type") question = self.question_factory.create(question_type.upper()) question.type = question_type question.id = ParserUtils.get_required_string(schema, "id") question.title = ParserUtils.get_required_string(schema, "title") question.number = ParserUtils.get_optional_string(schema, "number") question.description = ParserUtils.get_optional_string( schema, "description") question.skip_condition = ParserUtils.get_optional( schema, "skip_condition") question.guidance = ParserUtils.get_optional(schema, "guidance") # register the question questionnaire.register(question) if 'answers' in schema.keys(): for answer_schema in schema['answers']: question.add_answer( self._parse_answer(answer_schema, questionnaire)) else: raise SchemaParserException( 'Question must contain at least one answer') return question def _parse_answer(self, schema, questionnaire): """Parse a answer element :param schema: The answer schema :returns: A Answer object :raises: SchemaParserException """ answer_type = ParserUtils.get_required_string(schema, 'type') answer_id = ParserUtils.get_required_string(schema, 'id') answer = self.answer_factory.create(answer_type.upper(), answer_id) answer.type = answer_type answer.code = ParserUtils.get_optional_string(schema, 'q_code') answer.label = ParserUtils.get_optional_string(schema, 'label') answer.description = ParserUtils.get_optional_string( schema, 'description') answer.guidance = ParserUtils.get_optional_string(schema, 'guidance') answer.mandatory = ParserUtils.get_required_boolean( schema, 'mandatory') answer.options = ParserUtils.get_optional_array(schema, 'options') answer.alias = ParserUtils.get_optional_string(schema, 'alias') if 'validation' in schema.keys(): self._parse_validation(answer, schema['validation']) # register the answer questionnaire.register(answer) return answer @staticmethod def _parse_validation(answer, schema): if 'messages' in schema.keys(): messages = schema['messages'] for code, message in messages.items(): answer.messages[code] = message
class SchemaParser(AbstractSchemaParser): """SchemaParser class Implements the inteface defined in the AbstractSchemaParser class """ def __init__(self, schema): """Initialise the parser with the schema :param schema: the schema json object or dict """ self._version = "0.0.1" self._schema = schema self.answer_factory = Factory() self.answer_factory.register_all({ 'CHECKBOX': CheckboxAnswer, 'CURRENCY': CurrencyAnswer, 'DATE': DateAnswer, 'INTEGER': IntegerAnswer, 'PERCENTAGE': PercentageAnswer, 'POSITIVEINTEGER': PositiveIntegerAnswer, 'RADIO': RadioAnswer, 'TEXTAREA': TextareaAnswer, 'TEXTFIELD': TextfieldAnswer, }) self.question_factory = Factory() self.question_factory.register_all({ 'GENERAL': GeneralQuestion, 'DATERANGE': DateRangeQuestion, }) def get_parser_version(self): """Return which version of the parser :returns: The version number as a string, e.g. "0.0.1" """ return self._version def parse(self): """Parse the schema :returns: A questionnaire object :raises: A SchemaParserException if there is a problem while parsing the schema """ questionnaire = None try: questionnaire = Questionnaire() questionnaire.id = ParserUtils.get_required_string(self._schema, "questionnaire_id") questionnaire.eq_id = ParserUtils.get_required_string(self._schema, "eq_id") logger.debug("eq_id: " + questionnaire.eq_id) questionnaire.title = ParserUtils.get_required_string(self._schema, "title") questionnaire.survey_id = ParserUtils.get_required_string(self._schema, "survey_id") logger.debug("title: " + questionnaire.title) questionnaire.description = ParserUtils.get_required_string(self._schema, "description") questionnaire.theme = ParserUtils.get_required_string(self._schema, "theme") questionnaire.submission_page = ParserUtils.get_optional_string(self._schema, "submission_page", questionnaire.submission_page) except Exception as e: logging.error('Error parsing schema') logging.info(e) raise e if questionnaire: if "introduction" in self._schema.keys(): questionnaire.introduction = self._parse_introduction(self._schema['introduction']) if "groups" in self._schema.keys(): for group_schema in self._schema['groups']: questionnaire.add_group(self._parse_group(group_schema, questionnaire)) else: raise SchemaParserException('Questionnaire must contain at least one group') if 'messages' in self._schema.keys(): # re-use the parse validation method self._parse_validation(questionnaire, self._schema) return questionnaire def _parse_introduction(self, intro_schema): introduction = Introduction() introduction.legal = ParserUtils.get_optional_string(intro_schema, 'legal') introduction.description = ParserUtils.get_optional_string(intro_schema, 'description') introduction.information_to_provide = ParserUtils.get_optional_array(intro_schema, 'information_to_provide') return introduction def _parse_group(self, schema, questionnaire): """Parse a group element :param schema: The group schema :returns: Group object :raises: SchemaParserException """ group = None try: group = Group() group.id = ParserUtils.get_required_string(schema, "id") group.title = ParserUtils.get_optional_string(schema, "title") # Register the group questionnaire.register(group) except Exception as e: logging.error('Error parsing schema') logging.info(e) raise e if "blocks" in schema.keys(): for block_schema in schema['blocks']: group.add_block(self._parse_block(block_schema, questionnaire)) else: raise SchemaParserException('Group must contain at least one block') return group def _parse_block(self, schema, questionnaire): """Parse a block element :param schema: The block schema :returns: A Block object :raises: SchemaParserException """ block = Block() try: block.id = ParserUtils.get_required_string(schema, "id") block.title = ParserUtils.get_optional_string(schema, "title") block.routing_rules = ParserUtils.get_optional_array(schema, 'routing_rules') # register the block questionnaire.register(block) except Exception as e: logging.error('Error parsing schema') logging.info(e) raise e if "sections" in schema.keys(): for section_schema in schema['sections']: block.add_section(self._parse_section(section_schema, questionnaire)) else: raise SchemaParserException('Block must contain at least one section') return block def _parse_section(self, schema, questionnaire): """Parse a section element :param schema: The section schema :returns: A Section object :raises: SchemaParserException """ section = Section() try: section.id = ParserUtils.get_required_string(schema, "id") section.title = ParserUtils.get_optional_string(schema, "title") section.description = ParserUtils.get_optional_string(schema, "description") # regisger the section questionnaire.register(section) except Exception as e: logging.error('Error parsing schema') logging.info(e) raise e if 'questions' in schema.keys(): for question_schema in schema['questions']: section.add_question(self._parse_question(question_schema, questionnaire)) else: raise SchemaParserException('Section must have at least one question') return section def _parse_question(self, schema, questionnaire): """Parse a question element :param schema: The question schema :returns: A Question object :raises: SchemaParserException """ try: question_type = ParserUtils.get_required_string(schema, "type") question = self.question_factory.create(question_type.upper()) question.type = question_type question.id = ParserUtils.get_required_string(schema, "id") question.title = ParserUtils.get_required_string(schema, "title") question.description = ParserUtils.get_required_string(schema, "description") question.skip_condition = self._parse_skip_condition(ParserUtils.get_optional(schema, "skip_condition")) # register the question questionnaire.register(question) except Exception as e: logging.error('Error parsing schema') logging.info(e) raise e if 'answers' in schema.keys(): for answer_schema in schema['answers']: question.add_answer(self._parse_answer(answer_schema, questionnaire)) else: raise SchemaParserException('Question must contain at least one answer') return question def _parse_skip_condition(self, skip_condition_schema): if skip_condition_schema: skip_condition = SkipCondition() when_schema = ParserUtils.get_required(skip_condition_schema, "when") when = When() when.condition = ParserUtils.get_required(when_schema, 'condition') when.id = ParserUtils.get_required(when_schema, 'id') when.value = ParserUtils.get_required(when_schema, 'value') skip_condition.when = when return skip_condition else: return None def _parse_answer(self, schema, questionnaire): """Parse a answer element :param schema: The answer schema :returns: A Answer object :raises: SchemaParserException """ try: answer_type = ParserUtils.get_required_string(schema, 'type') answer_id = ParserUtils.get_required_string(schema, 'id') answer = self.answer_factory.create(answer_type.upper(), answer_id) answer.type = answer_type answer.code = ParserUtils.get_required_string(schema, 'q_code') answer.label = ParserUtils.get_optional_string(schema, 'label') answer.guidance = ParserUtils.get_optional_string(schema, 'guidance') answer.mandatory = ParserUtils.get_required_boolean(schema, 'mandatory') answer.options = ParserUtils.get_optional_array(schema, 'options') answer.alias = ParserUtils.get_optional_string(schema, 'alias') display = ParserUtils.get_optional(schema, "display") if display: answer.display = self._parse_display(display) if 'validation' in schema.keys(): self._parse_validation(answer, schema['validation']) # register the answer questionnaire.register(answer) except Exception as e: logging.error('Error parsing schema') logging.info(e) raise e return answer def _parse_validation(self, answer, schema): if 'messages' in schema.keys(): messages = schema['messages'] for code, message in messages.items(): answer.messages[code] = message def _parse_display(self, schema): """ Parse a display element :param schema: the display element :return: A display object """ display = Display() properties = ParserUtils.get_optional(schema, "properties") if properties: display.properties = self._parse_properties(properties) return display def _parse_properties(self, schema): """ Parse a properties element :param schema: the properties element :return: a properties object """ properties = Properties() try: properties.__dict__ = copy.deepcopy(schema) except Exception as e: logging.error('Error parsing schema') logging.info(e) raise e return properties