Make unit tests use a mock version of PyAudio, while making integration tests using the real version. If no real microphone is available, these integration tests are skipped. ref: N25B-119
98 lines
3.8 KiB
Python
98 lines
3.8 KiB
Python
import random
|
|
import sys
|
|
from StringIO import StringIO
|
|
|
|
import mock
|
|
|
|
from robot_interface.utils.microphone import choose_mic_default, choose_mic_interactive, get_microphones
|
|
|
|
|
|
class MicrophoneUtils(object):
|
|
"""Shared tests for any PyAudio-like implementation, e.g. mock and real."""
|
|
|
|
def test_choose_mic_default(self, pyaudio_instance):
|
|
"""
|
|
The result must contain at least "index", as this is used to identify the microphone.
|
|
The "name" is used for logging, so it should also exist.
|
|
It must have one or more channels.
|
|
Lastly it must be capable of sending at least 16000 samples per second.
|
|
"""
|
|
result = choose_mic_default(pyaudio_instance)
|
|
assert "index" in result
|
|
assert isinstance(result["index"], (int, long))
|
|
|
|
assert "name" in result
|
|
assert isinstance(result["name"], (str, unicode))
|
|
|
|
assert "maxInputChannels" in result
|
|
assert isinstance(result["maxInputChannels"], (int, long))
|
|
assert result["maxInputChannels"] > 0
|
|
|
|
assert "defaultSampleRate" in result
|
|
assert isinstance(result["defaultSampleRate"], float)
|
|
assert result["defaultSampleRate"] >= 16000
|
|
|
|
def test_choose_mic_interactive_input_not_int(self, pyaudio_instance, mocker):
|
|
"""
|
|
First mock an input that's not an integer, then a valid integer. There should be no errors.
|
|
"""
|
|
mock_input = mocker.patch("__builtin__.raw_input", side_effect=["not an integer", "0"])
|
|
fake_out = StringIO()
|
|
mocker.patch.object(sys, "stdout", fake_out)
|
|
|
|
result = choose_mic_interactive(pyaudio_instance)
|
|
assert "index" in result
|
|
assert isinstance(result["index"], (int, long))
|
|
assert result["index"] == 0
|
|
|
|
assert mock_input.called
|
|
|
|
assert any(p.startswith("Please enter a number") for p in fake_out.getvalue().splitlines())
|
|
|
|
def test_choose_mic_interactive_negative_index(self, pyaudio_instance, mocker):
|
|
"""
|
|
Make sure that the interactive method does not allow negative integers as input.
|
|
"""
|
|
mock_input = mocker.patch("__builtin__.raw_input", side_effect=["-1", "0"])
|
|
fake_out = StringIO()
|
|
mocker.patch.object(sys, "stdout", fake_out)
|
|
|
|
result = choose_mic_interactive(pyaudio_instance)
|
|
assert "index" in result
|
|
assert isinstance(result["index"], (int, long))
|
|
assert result["index"] == 0
|
|
|
|
assert mock_input.called
|
|
|
|
assert any(p.startswith("Please enter a number") for p in fake_out.getvalue().splitlines())
|
|
|
|
def test_choose_mic_interactive_index_too_high(self, pyaudio_instance, mocker):
|
|
"""
|
|
Make sure that the interactive method does not allow indices higher than the highest mic index.
|
|
"""
|
|
real_count = len(list(get_microphones(pyaudio_instance)))
|
|
mock_input = mocker.patch("__builtin__.raw_input", side_effect=[str(real_count), "0"])
|
|
fake_out = StringIO()
|
|
mocker.patch.object(sys, "stdout", fake_out)
|
|
|
|
result = choose_mic_interactive(pyaudio_instance)
|
|
assert "index" in result
|
|
assert isinstance(result["index"], (int, long))
|
|
|
|
assert mock_input.called
|
|
|
|
assert any(p.startswith("Please enter a number") for p in fake_out.getvalue().splitlines())
|
|
|
|
def test_choose_mic_interactive_random_index(self, pyaudio_instance, mocker):
|
|
"""
|
|
Get a random index from the list of available mics, make sure it's correct.
|
|
"""
|
|
microphones = list(get_microphones(pyaudio_instance))
|
|
random_index = random.randrange(len(microphones))
|
|
mocker.patch("__builtin__.raw_input", side_effect=[str(random_index)])
|
|
|
|
result = choose_mic_interactive(pyaudio_instance)
|
|
assert "index" in result
|
|
assert isinstance(result["index"], (int, long))
|
|
assert result["index"] == microphones[random_index]["index"]
|