# Copyright 2019 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 copy import deepcopy from unittest.mock import Mock from msm import MycroftSkillsManager from msm.skill_repo import SkillRepo from mycroft.configuration.config import LocalConf, DEFAULT_CONFIG __CONFIG = LocalConf(DEFAULT_CONFIG) class AnyCallable: """Class matching any callable. Useful for assert_called_with arguments. """ def __eq__(self, other): return callable(other) def base_config(): """Base config used when mocking. Preload to skip hitting the disk each creation time but make a copy so modifications don't mutate it. Returns: (dict) Mycroft default configuration """ return deepcopy(__CONFIG) def mock_msm(temp_dir): """Mock the MycroftSkillsManager because it reaches out to the internet.""" msm_mock = Mock(spec=MycroftSkillsManager) msm_mock.skills_dir = str(temp_dir) msm_mock.platform = 'test_platform' msm_mock.lock = Mock() msm_mock.repo = Mock(spec=SkillRepo) msm_mock.repo.get_default_skill_names = Mock(return_value=[ ('default', ['time', 'weather']), ('test_platform', ['test_skill']) ]) msm_mock.device_skill_state = dict( skills=[ dict(name='test_skill', beta=False) ] ) skill = Mock() skill.is_local = True skill.path = str(temp_dir) skill.skill_gid = 'test_skill|99.99' skill.meta_info = dict(display_name='Test Skill') msm_mock.list_all_defaults.return_value = [skill] msm_mock.default_skills = dict(test_skill=skill) msm_mock.all_skills = [skill] msm_mock.local_skills = dict(test_skill=skill) return msm_mock def mock_config(temp_dir): """Supply a reliable return value for the Configuration.get() method.""" get_config_mock = Mock() config = base_config() config['skills']['priority_skills'] = ['foobar'] config['data_dir'] = str(temp_dir) config['server']['metrics'] = False config['enclosure'] = {} get_config_mock.return_value = config return get_config_mock class MessageBusMock: """Replaces actual message bus calls in unit tests. The message bus should not be running during unit tests so mock it out in a way that makes it easy to test code that calls it. """ def __init__(self): self.message_types = [] self.message_data = [] self.event_handlers = [] def emit(self, message): self.message_types.append(message.msg_type) self.message_data.append(message.data) def on(self, event, _): self.event_handlers.append(event)