Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dinkum listener compat fixes with tests #154

Merged
merged 3 commits into from
May 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ovos_plugin_manager/templates/hotwords.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ def found_wake_word(self, frame_data):
"""
return False

def reset(self):
"""
Reset the WW engine to prepare for a new detection
"""
pass

def update(self, chunk):
"""Updates the hotword engine with new audio data.

Expand Down
8 changes: 4 additions & 4 deletions ovos_plugin_manager/templates/microphone.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

@dataclass
class Microphone:
sample_rate: int
sample_width: int
sample_channels: int
chunk_size: int
sample_rate: int = 16000
sample_width: int = 2
sample_channels: int = 1
chunk_size: int = 4096

@property
def frames_per_chunk(self) -> int:
Expand Down
92 changes: 92 additions & 0 deletions test/unittests/templates/test_microphone_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import unittest
from unittest.mock import patch, Mock

_TEST_CONFIG = {
"microphone": {
"module": "dummy",
"dummy": {
"sample_width": 1,
"sample_channels": 1,
"chunk_size": 2048
},
"ovos-microphone-plugin-alsa": {
"sample_width": 2,
"sample_channels": 1,
"chunk_size": 4096
}
}
}


class TestMicrophoneTemplate(unittest.TestCase):
def test_microphone_init(self):
from ovos_plugin_manager.templates.microphone import Microphone
# Default
mic = Microphone()
self.assertIsInstance(mic, Microphone)
self.assertIsInstance(mic.sample_rate, int)
self.assertIsInstance(mic.sample_width, int)
self.assertIsInstance(mic.sample_channels, int)
self.assertIsInstance(mic.chunk_size, int)

# Partial override with kwargs
mic_2 = Microphone(**_TEST_CONFIG['microphone']['dummy'])
self.assertIsInstance(mic_2, Microphone)
self.assertIsInstance(mic_2.sample_rate, int)
self.assertEqual(mic_2.sample_width, 1)
self.assertEqual(mic_2.sample_channels, 1)
self.assertEqual(mic_2.chunk_size, 2048)

# Override positional params
mic_3 = Microphone(1, 2, 3, 4)
self.assertIsInstance(mic_3, Microphone)
self.assertEqual(mic_3.sample_rate, 1)
self.assertEqual(mic_3.sample_width, 2)
self.assertEqual(mic_3.sample_channels, 3)
self.assertEqual(mic_3.chunk_size, 4)

self.assertNotEquals(mic, mic_2)
self.assertNotEquals(mic, mic_3)

def test_properties(self):
from ovos_plugin_manager.templates.microphone import Microphone
mic = Microphone()
self.assertIsInstance(mic.frames_per_chunk, int)
self.assertGreaterEqual(mic.frames_per_chunk, 0)
self.assertIsInstance(mic.seconds_per_chunk, float)
self.assertGreaterEqual(mic.seconds_per_chunk, 0)

def test_methods(self):
from ovos_plugin_manager.templates.microphone import Microphone
# Test failure cases
mic = Microphone()
with self.assertRaises(NotImplementedError):
mic.start()
with self.assertRaises(NotImplementedError):
mic.read_chunk()
with self.assertRaises(NotImplementedError):
mic.stop()

mock_start = Mock()
mock_read = Mock(return_value=b'1234')
mock_stop = Mock()

class MockMic(Microphone):
def start(self):
mock_start()

def read_chunk(self):
return mock_read()

def stop(self):
mock_stop()

# Test mic
mic = MockMic()
mic.start()
mock_start.assert_called_once()
chunk = mic.read_chunk()
self.assertEqual(chunk, b'1234')
mock_read.assert_called_once()
mic.stop()
mock_stop.assert_called_once()
66 changes: 66 additions & 0 deletions test/unittests/test_microphone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import unittest
from unittest.mock import patch, Mock
from copy import copy
from ovos_plugin_manager import PluginTypes

_TEST_CONFIG = {
"microphone": {
"module": "dummy",
"dummy": {
"sample_width": 1,
"sample_channels": 1,
"chunk_size": 2048
},
"ovos-microphone-plugin-alsa": {
"sample_width": 2,
"sample_channels": 1,
"chunk_size": 4096
}
}
}


class TestMicrophoneFactory(unittest.TestCase):
def test_create_microphone(self):
from ovos_plugin_manager.microphone import OVOSMicrophoneFactory
real_get_class = OVOSMicrophoneFactory.get_class
mock_class = Mock()
mock_get_class = Mock(return_value=mock_class)
OVOSMicrophoneFactory.get_class = mock_get_class

OVOSMicrophoneFactory.create(config=_TEST_CONFIG)
mock_get_class.assert_called_once_with(
{**_TEST_CONFIG['microphone']['dummy'], **{"module": "dummy"}})
mock_class.assert_called_once_with(_TEST_CONFIG['microphone']['dummy'])
OVOSMicrophoneFactory.get_class = real_get_class

@patch("ovos_plugin_manager.microphone.load_plugin")
def test_get_class(self, load_plugin):
mock = Mock()
load_plugin.return_value = mock
from ovos_plugin_manager.microphone import OVOSMicrophoneFactory
# Test valid module
module = OVOSMicrophoneFactory.get_class(_TEST_CONFIG)
load_plugin.assert_called_once_with("dummy",
PluginTypes.MIC)
self.assertEqual(mock, module)

def test_get_microphone_config(self):
from ovos_plugin_manager.microphone import get_microphone_config
config = copy(_TEST_CONFIG)
dummy_config = get_microphone_config(config)
self.assertEqual(dummy_config, {**_TEST_CONFIG['microphone']['dummy'],
**{'module': 'dummy',
'lang': 'en-us'}})
config = copy(_TEST_CONFIG)
config['microphone']['module'] = 'ovos-microphone-plugin-alsa'
alsa_config = get_microphone_config(config)
self.assertEqual(alsa_config,
{**_TEST_CONFIG['microphone']
['ovos-microphone-plugin-alsa'],
**{'module': 'ovos-microphone-plugin-alsa',
'lang': 'en-us'}})
config = copy(_TEST_CONFIG)
config['microphone']['module'] = 'fake'
fake_config = get_microphone_config(config)
self.assertEqual(fake_config, {'module': 'fake', 'lang': 'en-us'})