コード例 #1
0
    def test_single_sentence(self):
        """Single intent, single sentence."""
        intents = parse_ini("""
        [TestIntent]
        this is a test
        """)

        graph = intents_to_graph(intents)

        # Exact
        recognitions = zero_times(
            recognize("this is a test", graph, fuzzy=False))
        print(recognitions)
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent", confidence=1.0),
                    text="this is a test",
                    raw_text="this is a test",
                    tokens=["this", "is", "a", "test"],
                    raw_tokens=["this", "is", "a", "test"],
                )
            ],
        )

        # Too many tokens (lower confidence)
        recognitions = zero_times(
            recognize("this is a bad test", graph, fuzzy=False))
        self.assertFalse(recognitions)

        # Too few tokens (failure)
        recognitions = zero_times(recognize("this is a", graph, fuzzy=False))
        self.assertFalse(recognitions)
コード例 #2
0
    def test_stop_words(self):
        """Check sentence with stop words."""
        intents = parse_ini("""
        [TestIntent]
        this is a test
        """)

        graph = intents_to_graph(intents)

        # Lower confidence with no stop words
        recognitions = zero_times(recognize("this is a abcd test", graph))
        self.assertEqual(len(recognitions), 1)
        self.assertEqual(recognitions[0].intent.confidence, 1 - (1 / 4))

        # Higher confidence with stop words
        recognitions = zero_times(
            recognize("this is a abcd test", graph, stop_words={"abcd"}))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent",
                                  confidence=float(1 - (0.1 / 4))),
                    text="this is a test",
                    raw_text="this is a test",
                    tokens=["this", "is", "a", "test"],
                    raw_tokens=["this", "is", "a", "test"],
                )
            ],
        )
コード例 #3
0
    def test_stop_words(self):
        """Check sentence with stop words."""
        intents = parse_ini("""
        [TestIntent]
        this is a test
        """)

        graph = intents_to_graph(intents)

        # Failure without stop words
        recognitions = zero_times(
            recognize("this is a abcd test", graph, fuzzy=False))
        self.assertFalse(recognitions)

        # Success with stop words
        recognitions = zero_times(
            recognize("this is a abcd test",
                      graph,
                      stop_words={"abcd"},
                      fuzzy=False))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent", confidence=1.0),
                    text="this is a test",
                    raw_text="this is a test",
                    tokens=["this", "is", "a", "test"],
                    raw_tokens=["this", "is", "a", "test"],
                )
            ],
        )
コード例 #4
0
    def test_intent_filter(self):
        """Identical sentences from two different intents with filter."""
        intents = parse_ini("""
        [TestIntent1]
        this is a test

        [TestIntent2]
        this is a test
        """)

        graph = intents_to_graph(intents)

        def intent_filter(name):
            return name == "TestIntent1"

        # Should produce a recognition for first intent only
        recognitions = zero_times(
            recognize("this is a test", graph, intent_filter=intent_filter))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent1", confidence=1.0),
                    text="this is a test",
                    raw_text="this is a test",
                    tokens=["this", "is", "a", "test"],
                    raw_tokens=["this", "is", "a", "test"],
                )
            ],
        )
コード例 #5
0
    def test_multiple_sentences(self):
        """Identical sentences from two different intents."""
        intents = parse_ini("""
        [TestIntent1]
        this is a test

        [TestIntent2]
        this is a test
        """)

        graph = intents_to_graph(intents)

        # Should produce a recognition for each intent
        recognitions = zero_times(recognize("this is a test", graph))
        self.assertEqual(len(recognitions), 2)
        self.assertIn(
            Recognition(
                intent=Intent(name="TestIntent1", confidence=1.0),
                text="this is a test",
                raw_text="this is a test",
                tokens=["this", "is", "a", "test"],
                raw_tokens=["this", "is", "a", "test"],
            ),
            recognitions,
        )
        self.assertIn(
            Recognition(
                intent=Intent(name="TestIntent2", confidence=1.0),
                text="this is a test",
                raw_text="this is a test",
                tokens=["this", "is", "a", "test"],
                raw_tokens=["this", "is", "a", "test"],
            ),
            recognitions,
        )
コード例 #6
0
    def test_converter_args(self):
        """Check converter with arguments."""
        intents = parse_ini("""
        [TestIntent]
        this is a test ten:10!int!pow,3
        """)

        graph = intents_to_graph(intents)

        def pow_converter(*args, converter_args=None):
            exponent = int(converter_args[0]) if converter_args else 1
            return [x**exponent for x in args]

        # Should convert "ten" -> 10 -> 1000
        recognitions = zero_times(
            recognize(
                "this is a test ten",
                graph,
                fuzzy=False,
                extra_converters={"pow": pow_converter},
            ))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent", confidence=1.0),
                    text="this is a test 1000",
                    raw_text="this is a test ten",
                    tokens=["this", "is", "a", "test", 1000],
                    raw_tokens=["this", "is", "a", "test", "ten"],
                )
            ],
        )
コード例 #7
0
    def test_rules(self):
        """Make sure local and remote rules work."""
        intents = parse_ini("""
        [Intent1]
        rule = a test
        this is <rule>

        [Intent2]
        rule = this is
        <rule> <Intent1.rule>
        """)

        graph = intents_to_graph(intents)

        # Lower confidence with no stop words
        recognitions = zero_times(recognize("this is a test", graph))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="Intent1", confidence=1.0),
                    text="this is a test",
                    raw_text="this is a test",
                    tokens=["this", "is", "a", "test"],
                    raw_tokens=["this", "is", "a", "test"],
                ),
                Recognition(
                    intent=Intent(name="Intent2", confidence=1.0),
                    text="this is a test",
                    raw_text="this is a test",
                    tokens=["this", "is", "a", "test"],
                    raw_tokens=["this", "is", "a", "test"],
                ),
            ],
        )
コード例 #8
0
    def test_optional_entity(self):
        """Ensure entity inside optional is recognized."""
        ini_text = """
        [playBook]
        read me ($audio-book-name){book} in [the] [($assistant-zones){zone}]
        """

        replacements = {
            "$audio-book-name":
            [Sentence.parse("the hound of the baskervilles")],
            "$assistant-zones": [Sentence.parse("bedroom")],
        }

        graph = intents_to_graph(parse_ini(ini_text), replacements)

        recognitions = zero_times(
            recognize(
                "read me the hound of the baskervilles in the bedroom",
                graph,
                fuzzy=False,
            ))
        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertTrue(recognition.intent)

        entities = {e.entity: e for e in recognition.entities}
        self.assertIn("book", entities)
        book = entities["book"]
        self.assertEqual(book.value, "the hound of the baskervilles")

        self.assertIn("zone", entities)
        zone = entities["zone"]
        self.assertEqual(zone.value, "bedroom")
コード例 #9
0
    def test_slot_case_inside_substitution(self):
        """Ensure word casing doesn't interfere with group substitution."""
        ini_text = """
        [TestIntent]
        this is a ($test){value}
        """

        replacements = {
            "$test": [Sentence.parse("(Bar:bar | Baz:baz):barorbaz")]
        }
        graph = intents_to_graph(parse_ini(ini_text), replacements)

        recognitions = zero_times(
            recognize("this is a bar",
                      graph,
                      fuzzy=False,
                      word_transform=str.lower))
        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertIsNotNone(recognition.intent)

        # Check sequence substitution
        self.assertEqual(recognition.text, "this is a barorbaz")
        self.assertEqual(recognition.raw_text, "this is a bar")

        self.assertEqual(len(recognition.entities), 1)
        value = recognition.entities[0]
        self.assertEqual(value.entity, "value")
        self.assertEqual(value.value, "barorbaz")
        self.assertEqual(value.raw_value, "bar")
        self.assertEqual(value.source, "test")
コード例 #10
0
    def test_converters(self):
        """Check sentence with converters."""
        intents = parse_ini("""
        [TestIntent]
        this is a test!upper ten:10!int!square
        """)

        graph = intents_to_graph(intents)

        # Should upper-case "test" and convert "ten" -> 10 -> 100
        recognitions = zero_times(
            recognize(
                "this is a test ten",
                graph,
                fuzzy=False,
                extra_converters={
                    "square": lambda *args: [x**2 for x in args]
                },
            ))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent", confidence=1.0),
                    text="this is a TEST 100",
                    raw_text="this is a test ten",
                    tokens=["this", "is", "a", "TEST", 100],
                    raw_tokens=["this", "is", "a", "test", "ten"],
                )
            ],
        )
コード例 #11
0
    def test_word_case_preservation(self):
        """Ensure word casing is preserved in raw text."""
        ini_text = """
        [TestIntent]
        this is a (test){value}
        """

        graph = intents_to_graph(parse_ini(ini_text))

        recognitions = zero_times(
            recognize("this is a TEST",
                      graph,
                      fuzzy=False,
                      word_transform=str.lower))
        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertIsNotNone(recognition.intent)

        # Check sequence substitution
        self.assertEqual(recognition.text, "this is a test")
        self.assertEqual(recognition.raw_text, "this is a TEST")

        self.assertEqual(len(recognition.entities), 1)
        value = recognition.entities[0]
        self.assertEqual(value.entity, "value")
        self.assertEqual(value.value, "test")
        self.assertEqual(value.raw_value, "TEST")
コード例 #12
0
    def test_final_optional_entity(self):
        """Ensure final optional entity is matched."""

        ini_text = """
        [ChangeDisplay]
        display (top | bottom){location} [(page | layer){layout}]
        """

        graph = intents_to_graph(parse_ini(ini_text))

        recognitions = zero_times(recognize("display bottom layer", graph))

        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertIsNotNone(recognition.intent)

        entities = {e.entity: e for e in recognition.entities}

        self.assertIn("location", entities)
        location = entities["location"]
        self.assertEqual(location.value, "bottom")

        self.assertIn("layout", entities)
        layout = entities["layout"]
        self.assertEqual(layout.value, "layer")
コード例 #13
0
    def test_entity_converters_both(self):
        """Check sentence with an entity converter and a converter inside the entity."""
        intents = parse_ini("""
        [TestIntent]
        this is a test (four:4 point: two:2){number!floatify}
        """)

        graph = intents_to_graph(intents)

        # "four two" -> 4.2
        recognitions = zero_times(
            recognize(
                "this is a test four point two",
                graph,
                fuzzy=False,
                extra_converters={
                    "floatify": lambda a, b: [float(f"{a}.{b}")]
                },
            ))

        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertTrue(recognition.intent)

        entities = {e.entity: e for e in recognition.entities}
        self.assertIn("number", entities)
        number = entities["number"]
        self.assertEqual(number.value, 4.2)
コード例 #14
0
    def test_slot_sequence_replacement(self):
        """Ensure word sequences in slots can be replaced."""
        ini_text = """
        [PlayMusic]
        play me ($music_genre){genre}
        """

        replacements = {
            "$music_genre": [
                Sentence.parse("(rock | hard rock):(Hard Rock)"),
                Sentence.parse("classical:(Classical Music)"),
            ]
        }
        graph = intents_to_graph(parse_ini(ini_text), replacements)

        for text in ["play me rock", "play me hard rock"]:
            recognitions = zero_times(recognize(text, graph, fuzzy=False))
            self.assertEqual(len(recognitions), 1)
            recognition = recognitions[0]
            self.assertIsNotNone(recognition.intent)

            # Check sequence substitution
            self.assertEqual(recognition.text, "play me Hard Rock")

            # Check entity source
            self.assertEqual(len(recognition.entities), 1)
            genre = recognition.entities[0]
            self.assertEqual(genre.source, "music_genre")

        recognitions = zero_times(
            recognize("play me classical", graph, fuzzy=False))
        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertIsNotNone(recognition.intent)

        # Check sequence substitution
        self.assertEqual(recognition.text, "play me Classical Music")

        # Check entity source
        self.assertEqual(len(recognition.entities), 1)
        genre = recognition.entities[0]
        self.assertEqual(genre.source, "music_genre")
コード例 #15
0
    def test_entity_converter(self):
        """Check sentence with an entity converter."""
        intents = parse_ini("""
        [TestIntent]
        this is a test (four: point: two:4.2){number!float}
        """)

        graph = intents_to_graph(intents)

        # "four point two" -> 4.2
        recognitions = zero_times(
            recognize("this is a test four point two", graph, fuzzy=False))

        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertTrue(recognition.intent)

        entities = {e.entity: e for e in recognition.entities}
        self.assertIn("number", entities)
        number = entities["number"]
        self.assertEqual(number.value, 4.2)
コード例 #16
0
    def test_converters_in_entities(self):
        """Check sentence with converters inside an entity."""
        intents = parse_ini("""
        [TestIntent]
        this is a test (ten:10!int){number}
        """)

        graph = intents_to_graph(intents)

        # ten -> 10 (int)
        recognitions = zero_times(
            recognize("this is a test ten", graph, fuzzy=False))

        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertTrue(recognition.intent)

        entities = {e.entity: e for e in recognition.entities}
        self.assertIn("number", entities)
        number = entities["number"]
        self.assertEqual(number.value, 10)
コード例 #17
0
    def test_sequence_converters(self):
        """Check sentence with sequence converters."""
        intents = parse_ini("""
        [TestIntent]
        this (is a test)!upper
        """)

        graph = intents_to_graph(intents)

        # Should upper-case "is a test"
        recognitions = zero_times(
            recognize("this is a test", graph, fuzzy=False))
        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent", confidence=1.0),
                    text="this IS A TEST",
                    raw_text="this is a test",
                    tokens=["this", "IS", "A", "TEST"],
                    raw_tokens=["this", "is", "a", "test"],
                )
            ],
        )
コード例 #18
0
    def test_drop_group(self):
        """Test dropping a group."""
        intents = parse_ini("""
        [TestIntent]
        this is (a | another): test
        """)

        graph = intents_to_graph(intents)

        recognitions = zero_times(
            recognize("this is a test", graph, fuzzy=False))

        self.assertEqual(
            recognitions,
            [
                Recognition(
                    intent=Intent(name="TestIntent", confidence=1.0),
                    text="this is test",
                    raw_text="this is a test",
                    tokens=["this", "is", "test"],
                    raw_tokens=["this", "is", "a", "test"],
                )
            ],
        )
コード例 #19
0
    def test_strict_simple(self):
        """Check exact parse."""
        recognitions = zero_times(
            recognize("set a timer for ten minutes", self.graph, fuzzy=False))
        self.assertEqual(len(recognitions), 1)
        recognition = recognitions[0]
        self.assertTrue(recognition.intent)

        self.assertEqual(
            recognition.entities,
            [
                Entity(
                    entity="minutes",
                    value="10",
                    raw_value="ten",
                    start=16,
                    raw_start=16,
                    raw_end=19,
                    end=18,
                    tokens=["10"],
                    raw_tokens=["ten"],
                )
            ],
        )