def test_simple_arrow_and_hash_at_end(self): graph = PatternGraph() pattern_element1 = ET.fromstring("<pattern>A ^</pattern>") pattern_element2 = ET.fromstring("<pattern>A #</pattern>") topic_element = ET.fromstring("<topic>*</topic>") that_element = ET.fromstring("<that>*</that>") template_node1 = TemplateNode() template_node2 = TemplateNode() graph.add_pattern_to_graph(pattern_element1, topic_element, that_element, template_node1) graph.add_pattern_to_graph(pattern_element2, topic_element, that_element, template_node2) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(result.template, template_node2) self.assertEqual(1, len(pattern_stars)) self.assertEqual('C', pattern_stars[0]) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0)
def test_mixed_priorty_and_star(self): graph = PatternGraph() pattern_element1 = ET.fromstring("<pattern>A $B C</pattern>") pattern_element2 = ET.fromstring("<pattern>A * C</pattern>") pattern_element3 = ET.fromstring("<pattern>A D C</pattern>") topic_element = ET.fromstring("<topic>*</topic>") that_element = ET.fromstring("<that>*</that>") template_node1 = TemplateNode() template_node2 = TemplateNode() template_node3 = TemplateNode() graph.add_pattern_to_graph(pattern_element1, topic_element, that_element, template_node1) graph.add_pattern_to_graph(pattern_element2, topic_element, that_element, template_node2) graph.add_pattern_to_graph(pattern_element3, topic_element, that_element, template_node3) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A B C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(result.template, template_node1) self.assertEqual(len(pattern_stars), 0) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A F C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(result.template, template_node2) self.assertEqual(len(pattern_stars), 1) self.assertEqual("F", pattern_stars[0]) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A D C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(result.template, template_node3) self.assertEqual(len(pattern_stars), 0) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0)
def parse_interval_expression(self, expression, branch): # TemplateInternalNode # aise ParserException ("Error, interval not implemented!") interval_node = TemplateIntervalNode() branch.children.append(interval_node) if 'format' in expression.attrib: interval_node.format = TemplateWordNode( expression.attrib['format']) head_text = self.get_text_from_element(expression) self.parse_text(head_text, interval_node) for child in expression: if child.tag == 'format': interval_node.format = TemplateWordNode( self.get_text_from_element(child)) elif child.tag == 'style': node = TemplateNode() self.parse_text(self.get_text_from_element(child), node) for sub_child in child: self.parse_tag_expression(sub_child, node) self.parse_text(self.get_text_from_element(child), node) interval_node.style = node elif child.tag == 'from': node = TemplateNode() self.parse_text(self.get_text_from_element(child), node) for sub_child in child: self.parse_tag_expression(sub_child, node) self.parse_text(self.get_text_from_element(child), node) interval_node.interval_from = node elif child.tag == 'to': node = TemplateNode() self.parse_text(self.get_text_from_element(child), node) for sub_child in child: self.parse_tag_expression(sub_child, node) self.parse_text(self.get_text_from_element(child), node) interval_node.interval_to = node else: self.parse_tag_expression(child, interval_node) tail_text = self.get_tail_from_element(child) self.parse_text(tail_text, interval_node) if interval_node.format is None: logging.warning("Interval node, format missing !") if interval_node.style is None: logging.warning("style node, format missing !") if interval_node.interval_from is None: logging.warning("interval_from node, format missing !") if interval_node.interval_to is None: logging.warning("interval_to node, format missing !")
def test_multiple_templates(self): node1 = PatternTemplateNode(TemplateNode()) node2 = PatternTemplateNode(TemplateNode()) with self.assertRaises(ParserException) as raised: node1.can_add(node2) self.assertEqual(str(raised.exception), "Cannot add template node to template node")
def test_multi_star_multi_branch_star(self): graph = PatternGraph() pattern_element1 = ET.fromstring("<pattern>A * B * C</pattern>") pattern_element2 = ET.fromstring("<pattern>A * C * D</pattern>") topic_element = ET.fromstring("<topic>*</topic>") that_element = ET.fromstring("<that>*</that>") template_node = TemplateNode() graph.add_pattern_to_graph(pattern_element1, topic_element, that_element, template_node) graph.add_pattern_to_graph(pattern_element2, topic_element, that_element, template_node) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A X B Y C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(2, len(pattern_stars)) self.assertEqual('X', pattern_stars[0]) self.assertEqual('Y', pattern_stars[1]) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0)
def test_simple_topic_and_star(self): graph = PatternGraph() pattern_element = ET.fromstring("<pattern>A * D</pattern>") topic_element = ET.fromstring("<topic>TOPIC1</topic>") that_element = ET.fromstring("<that>*</that>") template_node = TemplateNode() graph.add_pattern_to_graph(pattern_element, topic_element, that_element, template_node) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A B C D"), pattern_stars, Sentence("TOPIC1"), topic_stars, Sentence("THAT1"), that_stars) self.assertIsNotNone(result) self.assertEqual(len(pattern_stars), 1) self.assertEqual('B C', pattern_stars[0]) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 1) self.assertEqual('THAT1', that_stars[0])
def test_multiple_hashes_with_star_and_that(self): graph = PatternGraph() pattern_element = ET.fromstring("<pattern>A # # D</pattern>") topic_element = ET.fromstring("<topic>*</topic>") that_element = ET.fromstring("<that>THAT</that>") template_node = TemplateNode() graph.add_pattern_to_graph(pattern_element, topic_element, that_element, template_node) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A B C C2 D"), pattern_stars, Sentence("THIS"), topic_stars, Sentence("THAT"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(len(pattern_stars), 2) self.assertEqual('B', pattern_stars[0]) self.assertEqual('C C2', pattern_stars[1]) self.assertEqual(len(topic_stars), 1) self.assertEqual("THIS", topic_stars[0]) self.assertEqual(len(that_stars), 0)
def test_simple_star_at_end(self): graph = PatternGraph() pattern_element = ET.fromstring("<pattern>A B *</pattern>") topic_element = ET.fromstring("<topic>*</topic>") that_element = ET.fromstring("<that>*</that>") template_node = TemplateNode() graph.add_pattern_to_graph(pattern_element, topic_element, that_element, template_node) matcher = PatternMatcher(graph) pattern_stars = [] topic_stars = [] that_stars = [] result = matcher.match(PatternMatcherTests.bot, PatternMatcherTests.clientid, Sentence("A B C"), pattern_stars, Sentence("*"), topic_stars, Sentence("*"), that_stars) self.assertIsNotNone(result) self.assertIsInstance(result, PatternTemplateNode) self.assertEqual(len(pattern_stars), 1) self.assertEqual('C', pattern_stars[0]) self.assertEqual(len(topic_stars), 0) self.assertEqual(len(that_stars), 0)
def test_init(self): node = PatternTemplateNode(TemplateNode()) self.assertIsNotNone(node) self.assertFalse(node.is_root()) self.assertFalse(node.is_priority()) self.assertFalse(node.is_wildcard()) self.assertFalse(node.is_zero_or_more()) self.assertFalse(node.is_one_or_more()) self.assertIsNotNone(node.children) self.assertFalse(node.has_children()) self.assertTrue(node.equivalent(PatternTemplateNode(TemplateNode()))) self.assertEqual( node.to_string(), "PTEMPLATE [P(0)^(0)#(0)C(0)_(0)*(0)To(0)Th(0)Te(1)] ")
def get_condition_value(self, condition, raise_on_missing=True): if 'value' in condition.attrib: value_node = TemplateNode() value_node.append(TemplateWordNode(condition.attrib['value'])) return value_node #return condition.attrib['value'] else: values = condition.findall('value') if len(values) == 0: if raise_on_missing is True: raise ParserException("Error, element has no value", xml_element=condition) else: return None elif len(values) > 1: if raise_on_missing is True: raise ParserException( "Error, element has multiple value elements", xml_element=condition) else: return None else: value_node = TemplateNode() self.parse_template_node(values[0], value_node) return value_node
def parse_bot_expression(self, expression, branch): bot_node = TemplateBotNode() branch.children.append(bot_node) name_found = False if 'name' in expression.attrib: node = TemplateNode() name_node = TemplateWordNode(expression.attrib['name']) node.append(name_node) name_found = True bot_node.name = node self.parse_text(self.get_text_from_element(expression), bot_node) for child in expression: if child.tag == 'name': node = TemplateNode() self.parse_text(self.get_text_from_element(child), node) for sub_child in child: self.parse_tag_expression(sub_child, node) self.parse_text(self.get_text_from_element(child), node) bot_node.name = node name_found = True else: self.parse_tag_expression(child, bot_node) self.parse_text(self.get_tail_from_element(child), bot_node) if name_found is False: raise ParserException("Error, name not found", xml_element=expression)
def parse_random_expression(self, expression, branch): random_node = TemplateRandomNode() branch.children.append(random_node) li_found = False for child in expression: if child.tag == 'li': li_found = True li_node = TemplateNode() random_node.children.append(li_node) self.parse_template_node(child, li_node) else: raise ParserException("Error, unsupported random child tag: %s" % (child.tag), xml_element=expression) if li_found is False: raise ParserException("Error, no li children of random element!", xml_element=expression)
def evaluate(self, bot: Bot, clientid: str, template_node: TemplateNode): logging.debug("Evaluating node [%s]", template_node.to_string()) template_node.output() return template_node.resolve(bot, clientid)
def parse_template_expression(self, pattern): node = TemplateNode() self.parse_template_node(pattern, node) return node
def parse_set_expression(self, expression, branch): set_node = TemplateSetNode() branch.children.append(set_node) name_found = False var_found = False if 'name' in expression.attrib: node = TemplateNode() name_node = TemplateWordNode(expression.attrib['name']) node.append(name_node) set_node.local = False name_found = True set_node.name = node if 'var' in expression.attrib: node = TemplateNode() name_node = TemplateWordNode(expression.attrib['var']) node.append(name_node) set_node.local = True var_found = True set_node.name = node self.parse_text(self.get_text_from_element(expression), set_node) for child in expression: if child.tag == 'name': node = TemplateNode() self.parse_text(self.get_text_from_element(child), node) for sub_child in child: self.parse_tag_expression(sub_child, node) self.parse_text(self.get_text_from_element(child), node) set_node.name = node set_node.local = False name_found = True elif child.tag == 'var': node = TemplateNode() self.parse_text(self.get_text_from_element(child), node) for sub_child in child: self.parse_tag_expression(sub_child, node) self.parse_text(self.get_text_from_element(child), node) set_node.name = node set_node.local = True var_found = True else: self.parse_tag_expression(child, set_node) self.parse_text(self.get_tail_from_element(child), set_node) if name_found is True and var_found is True: raise ParserException( "Error, set node has both name AND var values", xml_element=expression) if name_found is False and var_found is False: raise ParserException( "Error, set node has both name AND var values", xml_element=expression)