From 31dfb2d57333fd5d37fe6b27a7db3b6418cd1fd1 Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 12:07:04 +0100 Subject: [PATCH] fix:port tests from core --- ovos_padatious/opm.py | 16 +++--- tests/test_intent_serv.py | 109 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 tests/test_intent_serv.py diff --git a/ovos_padatious/opm.py b/ovos_padatious/opm.py index 158cbc7..f26786d 100644 --- a/ovos_padatious/opm.py +++ b/ovos_padatious/opm.py @@ -105,18 +105,22 @@ def __init__(self, bus: Optional[Union[MessageBusClient, FakeBus]] = None, self.containers = {lang: PadatiousIntentContainer(f"{intent_cache}/{lang}") for lang in langs} - self.bus.on('padatious:register_intent', self.register_intent) - self.bus.on('padatious:register_entity', self.register_entity) - self.bus.on('detach_intent', self.handle_detach_intent) - self.bus.on('detach_skill', self.handle_detach_skill) - self.bus.on('mycroft.skills.initialized', self.train) - self.finished_training_event = Event() self.finished_initial_train = False self.registered_intents = [] self.registered_entities = [] self.max_words = 50 # if an utterance contains more words than this, don't attempt to match + + self.bus.on('padatious:register_intent', self.register_intent) + self.bus.on('padatious:register_entity', self.register_entity) + self.bus.on('detach_intent', self.handle_detach_intent) + self.bus.on('detach_skill', self.handle_detach_skill) + self.bus.on('mycroft.skills.initialized', self.train) + self.bus.on('intent.service.padatious.get', self.handle_get_padatious) + self.bus.on('intent.service.padatious.manifest.get', self.handle_padatious_manifest) + self.bus.on('intent.service.padatious.entities.manifest.get', self.handle_entity_manifest) + LOG.debug('Loaded Padatious intent parser.') @property diff --git a/tests/test_intent_serv.py b/tests/test_intent_serv.py new file mode 100644 index 0000000..24a9a88 --- /dev/null +++ b/tests/test_intent_serv.py @@ -0,0 +1,109 @@ +# Copyright 2017 Mycroft AI Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from unittest import TestCase, mock + +from ovos_bus_client.message import Message + +from ovos_padatious.opm import PadatiousPipeline + + +def create_intent_msg(keyword, value): + """Create a message for registering a padatious intent.""" + return Message('padatious:register_intent', + {'name': f"skill:{keyword}", 'samples': [value]}, + {"skill_id": "skill"}) + + +def create_entity_msg(keyword, value): + """Create a message for registering a padatious entity.""" + return Message('padatious:register_entity', + {'name': f"skill:{keyword}", 'samples': [value]}, + {"skill_id": "skill"}) + + +def get_last_message(bus): + """Get last sent message on mock bus.""" + last = bus.emit.call_args + return last[0][0] + + +class TestIntentServiceApi(TestCase): + def setUp(self): + self.intent_service = PadatiousPipeline(mock.Mock()) + self.setup_simple_padatious_intent() + + def setup_simple_padatious_intent(self, + msg=create_intent_msg('testIntent', 'test'), + msg2=create_entity_msg('testEntity', 'enty')): + self.intent_service.register_intent(msg) + self.intent_service.register_entity(msg2) + + def test_get_padatious_intent(self): + # Check that the intent is returned + msg = Message('intent.service.padatious.get', + data={'utterance': 'test'}) + self.intent_service.handle_get_padatious(msg) + + reply = get_last_message(self.intent_service.bus) + + self.assertEqual(reply.data['intent']['name'], + 'skill:testIntent') + + def test_get_padatious_intent_no_match(self): + """Check that if the intent doesn't match at all None is returned.""" + # Check that no intent is matched + msg = Message('intent.service.padatious.get', + data={'utterance': 'five'}) + self.intent_service.handle_get_padatious(msg) + reply = get_last_message(self.intent_service.bus) + self.assertLess(reply.data["intent"]['conf'], 0.4) + + def test_get_padatious_intent_manifest(self): + """Make sure the manifest returns a list of Intent Parser objects.""" + msg = Message('intent.service.padatious.manifest.get') + self.intent_service.handle_padatious_manifest(msg) + reply = get_last_message(self.intent_service.bus) + self.assertEqual(reply.data['intents'][0], 'skill:testIntent') + + def test_get_padatious_vocab_manifest(self): + msg = Message('intent.service.padatious.entities.manifest.get') + self.intent_service.handle_entity_manifest(msg) + reply = get_last_message(self.intent_service.bus) + value = reply.data["entities"][0]['name'] + keyword = reply.data["entities"][0]['samples'][0] + self.assertEqual(value, 'skill:testEntity') + self.assertEqual(keyword, 'enty') + + def test_get_no_match_after_detach(self): + """Check that a removed intent doesn't match.""" + # Check that no intent is matched + msg = Message('detach_intent', + data={'intent_name': 'skill:testIntent'}) + self.intent_service.handle_detach_intent(msg) + msg = Message('intent.service.padatious.get', data={'utterance': 'test'}) + self.intent_service.handle_get_padatious(msg) + reply = get_last_message(self.intent_service.bus) + self.assertEqual(reply.data['intent'], None) + + def test_get_no_match_after_detach_skill(self): + """Check that a removed skill's intent doesn't match.""" + # Check that no intent is matched + msg = Message('detach_intent', + data={'skill_id': 'skill'}) + self.intent_service.handle_detach_skill(msg) + msg = Message('intent.service.padatious.get', data={'utterance': 'test'}) + self.intent_service.handle_get_padatious(msg) + reply = get_last_message(self.intent_service.bus) + self.assertEqual(reply.data['intent'], None)