def test_den_overhead(self): """Sequence of optionals/alternatives plus tag substitution.""" s = Sentence.parse( "toggle [the] (den | playroom) [light] {light_name:den_overhead}") self.assertEqual( s.items, [ Word("toggle"), Sequence( text="the", type=SequenceType.ALTERNATIVE, items=[Word("the"), Word("")], ), Sequence( text="den | playroom", type=SequenceType.GROUP, items=[ Sequence( text="den | playroom", type=SequenceType.ALTERNATIVE, items=[Word("den"), Word("playroom")], ) ], ), Sequence( text="light", type=SequenceType.ALTERNATIVE, items=[Word("light"), Word("")], tag=Tag(tag_text="light_name", substitution="den_overhead"), ), ], )
def test_tagged_group_in_optional(self): """Tagged group inside an optional.""" s = Sentence.parse("this is a [($test){tag}]") self.assertEqual( s.items, [ Word("this"), Word("is"), Word("a"), Sequence( text="($test){tag}", type=SequenceType.ALTERNATIVE, items=[ Sequence( text="$test", type=SequenceType.GROUP, tag=Tag(tag_text="tag"), items=[ SlotReference(slot_name="test", text="$test") ], ), Word(""), ], ), ], )
def test_sequence_substition_in_alternative(self): """Test sequence substitution inside an alternative.""" s = Sentence.parse( "((light one):light_1 | (light two):light_2) {name} :domain{light}" ) self.assertEqual( s.items, [ Sequence( text="(light one):light_1 | (light two):light_2", type=SequenceType.ALTERNATIVE, tag=Tag(tag_text="name"), items=[ Sequence( text="light one", substitution="light_1", type=SequenceType.GROUP, items=[Word("light"), Word("one")], ), Sequence( text="light two", substitution="light_2", type=SequenceType.GROUP, items=[Word("light"), Word("two")], ), ], ), Word(text="", substitution="domain", tag=Tag(tag_text="light")), ], )
def test_nested_optionals(self): """Optional inside an optional.""" s = Sentence.parse("this [[is] a] test") self.assertEqual( s.items, [ Word("this"), Sequence( text="[is] a", type=SequenceType.ALTERNATIVE, items=[ Sequence( text="[is] a", type=SequenceType.GROUP, items=[ Sequence( text="is", type=SequenceType.ALTERNATIVE, items=[Word("is"), Word("")], ), Word("a"), ], ), Word(""), ], ), Word("test"), ], )
def test_escape(self): """Test escaped optional.""" ini_text = """ [TestIntent1] \\[this] is a test """ intents = parse_ini(ini_text) self.assertEqual( intents, { "TestIntent1": [ Sentence( text="[this] is a test", items=[ Sequence( text="this", type=SequenceType.ALTERNATIVE, items=[Word("this"), Word("")], ), Word("is"), Word("a"), Word("test"), ], ) ] }, )
def test_final_optional_entity(self): """Ensure final optional entity has tag.""" ini_text = """ [ChangeDisplay] display [(page | layer){layout}] """ intents = parse_ini(ini_text) self.assertEqual( intents, { "ChangeDisplay": [ Sentence( text="display [(page | layer){layout}]", items=[ Word("display"), Sequence( text="(page | layer){layout}", type=SequenceType.ALTERNATIVE, items=[ Sequence( text="page | layer", type=SequenceType.GROUP, tag=Tag(tag_text="layout"), items=[ Sequence( text="page | layer", type=SequenceType.ALTERNATIVE, items=[ Word("page"), Word("layer") ], ) ], ), Word(""), ], ), ], ) ] }, )
def test_walk(self): """Test walk_expression.""" s = Sentence.parse("set alarm for (2 | 3) minutes") def num2words(word): if not isinstance(word, Word): return try: n = int(word.text) if n == 2: word.text = "two" word.substitution = "2" elif n == 3: word.text = "three" word.substitution = "3" except ValueError: pass walk_expression(s, num2words) self.assertEqual( s.items, [ Word("set"), Word("alarm"), Word("for"), Sequence( text="2 | 3", type=SequenceType.GROUP, items=[ Sequence( text="2 | 3", type=SequenceType.ALTERNATIVE, items=[ Word("two", substitution="2"), Word("three", substitution="3"), ], ) ], ), Word("minutes"), ], )
def test_implicit_sequences(self): """Implicit sequences around alternative.""" s = Sentence.parse("this is | a test") self.assertEqual(s.type, SequenceType.ALTERNATIVE) self.assertEqual( s.items, [ Sequence( text="this is", type=SequenceType.GROUP, items=[Word("this"), Word("is")], ), Sequence( text="a test", type=SequenceType.GROUP, items=[Word("a"), Word("test")], ), ], )
def test_alternative(self): """Basic alternative.""" s = Sentence.parse("this (is | a) test") self.assertEqual( s.items, [ Word("this"), Sequence( text="is | a", type=SequenceType.GROUP, items=[ Sequence( text="is | a", type=SequenceType.ALTERNATIVE, items=[Word("is"), Word("a")], ) ], ), Word("test"), ], )
def test_optional_alternative(self): """Combined optional and alternative.""" s = Sentence.parse("this [is | a] test") self.assertEqual( s.items, [ Word("this"), Sequence( text="is | a", type=SequenceType.ALTERNATIVE, items=[ Sequence( text="is | a", type=SequenceType.ALTERNATIVE, items=[Word("is"), Word("a")], ), Word(""), ], ), Word("test"), ], )
def test_optional(self): """Basic optional.""" s = Sentence.parse("this is [a] test") self.assertEqual( s.items, [ Word("this"), Word("is"), Sequence(text="a", type=SequenceType.ALTERNATIVE, items=[Word("a"), Word("")]), Word("test"), ], )
def test_alternative_substitution(self): """Alternative substitution.""" s = Sentence.parse("this [is a]:isa test") self.assertEqual( s.items, [ Word("this"), Sequence( text="is a", type=SequenceType.ALTERNATIVE, substitution="isa", items=[ Sequence( text="is a", type=SequenceType.GROUP, items=[Word("is"), Word("a")], ), Word(""), ], ), Word("test"), ], )
def test_walk(self): """Test Expression.walk with rule and slot reference.""" ini_text = """ [SetAlarm] minutes = $minute minutes set alarm for <minutes> """ intents = parse_ini(ini_text) sentences, replacements = split_rules(intents) replacements["$minute"] = [Sentence.parse("2 | 3")] def num2words(word): if not isinstance(word, Word): return try: n = int(word.text) if n == 2: word.text = "two" word.substitution = "2" elif n == 3: word.text = "three" word.substitution = "3" except ValueError: pass for s in sentences["SetAlarm"]: walk_expression(s, num2words, replacements) # Verify minute digits were replaced minute = replacements["$minute"][0] self.assertEqual( minute, Sentence( text="2 | 3", type=SequenceType.GROUP, items=[ Sequence( text="2 | 3", type=SequenceType.ALTERNATIVE, items=[ Word("two", substitution="2"), Word("three", substitution="3"), ], ) ], ), )
def num2words(word): if not isinstance(word, Word): return try: n = int(word.text) if n == 23: return Sequence( text="23", type=SequenceType.GROUP, items=[Word("twenty"), Word("three")], substitution="23", ) except ValueError: pass
def test_tag_alternative(self): """Tag an alternative.""" s = Sentence.parse("[this is a]{test}") self.assertEqual(s.tag, Tag(tag_text="test")) self.assertEqual( s.items, [ Sequence( text="this is a", type=SequenceType.GROUP, items=[Word("this"), Word("is"), Word("a")], ), Word(""), ], )
def test_substitution_and_converters(self): """Test substitution and converters on a sequence""" s = Sentence.parse("this (is a):test!c1!c2") self.assertEqual( s.items, [ Word("this"), Sequence( text="is a", type=SequenceType.GROUP, items=[Word("is"), Word("a")], substitution="test", converters=["c1", "c2"], ), ], )
def test_sequence_converters(self): """Test multiple converters on a sequence""" s = Sentence.parse("this (is a test)!c1!c2") self.assertEqual( s.items, [ Word("this"), Sequence( text="is a test", type=SequenceType.GROUP, items=[Word("is"), Word("a"), Word("test")], converters=["c1", "c2"], ), ], )
def test_implicit_sequence_with_rule(self): """Implicit sequence around alternative with a rule reference.""" s = Sentence.parse("this | is a <test>") self.assertEqual(s.type, SequenceType.ALTERNATIVE) self.assertEqual( s.items, [ Word("this"), Sequence( text="is a <test>", type=SequenceType.GROUP, items=[ Word("is"), Word("a"), RuleReference(text="<test>", rule_name="test"), ], ), ], )
def test_walk_multiple_words(self): """Test walk_expression with a multi-word replacement.""" s = Sentence.parse("set alarm for 23 minutes") def num2words(word): if not isinstance(word, Word): return try: n = int(word.text) if n == 23: return Sequence( text="23", type=SequenceType.GROUP, items=[Word("twenty"), Word("three")], substitution="23", ) except ValueError: pass walk_expression(s, num2words) self.assertEqual( s.items, [ Word("set"), Word("alarm"), Word("for"), Sequence( text="23", type=SequenceType.GROUP, items=[Word("twenty"), Word("three")], substitution="23", ), Word("minutes"), ], )