This was created with the assumption that all devices were choosable, but now only ones with input channels are. ref: N25B-119
159 lines
5.9 KiB
Python
159 lines
5.9 KiB
Python
from __future__ import unicode_literals # So that we can format strings with Unicode characters
|
|
import random
|
|
import sys
|
|
from StringIO import StringIO
|
|
|
|
from robot_interface.utils.microphone import (
|
|
choose_mic_default,
|
|
choose_mic_interactive,
|
|
choose_mic_arguments,
|
|
choose_mic,
|
|
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.
|
|
"""
|
|
microphones = get_microphones(pyaudio_instance)
|
|
target_microphone = next(microphones)
|
|
|
|
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"] == target_microphone["index"]
|
|
|
|
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.
|
|
"""
|
|
microphones = get_microphones(pyaudio_instance)
|
|
target_microphone = next(microphones)
|
|
|
|
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"] == target_microphone["index"]
|
|
|
|
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"]
|
|
|
|
def test_choose_mic_no_arguments(self, pyaudio_instance, mocker):
|
|
mocker.patch.object(sys, "argv", [])
|
|
|
|
result = choose_mic_arguments(pyaudio_instance)
|
|
|
|
assert result is None
|
|
|
|
def test_choose_mic_arguments(self, pyaudio_instance, mocker):
|
|
for mic in get_microphones(pyaudio_instance):
|
|
mocker.patch.object(sys, "argv", ["--microphone", mic["name"]])
|
|
|
|
result = choose_mic_arguments(pyaudio_instance)
|
|
|
|
assert result is not None
|
|
assert result == mic
|
|
|
|
def test_choose_mic_arguments_eq(self, pyaudio_instance, mocker):
|
|
for mic in get_microphones(pyaudio_instance):
|
|
mocker.patch.object(sys, "argv", ["--microphone={}".format(mic["name"])])
|
|
|
|
result = choose_mic_arguments(pyaudio_instance)
|
|
|
|
assert result is not None
|
|
assert result == mic
|
|
|
|
def test_choose_mic_arguments_not_exits(self, pyaudio_instance, mocker):
|
|
mocker.patch.object(sys, "argv", ["--microphone", "Surely this microphone doesn't exist"])
|
|
|
|
result = choose_mic_arguments(pyaudio_instance)
|
|
|
|
assert result is None
|
|
|
|
def test_choose_mic_with_argument(self, pyaudio_instance, mocker):
|
|
mic = next(get_microphones(pyaudio_instance))
|
|
mocker.patch.object(sys, "argv", ["--microphone", mic["name"]])
|
|
|
|
result = choose_mic(pyaudio_instance)
|
|
|
|
assert result is not None
|
|
assert result == mic
|
|
|
|
def test_choose_mic_no_argument(self, pyaudio_instance, mocker):
|
|
default_mic = choose_mic_default(pyaudio_instance)
|
|
mocker.patch.object(sys, "argv", [])
|
|
|
|
result = choose_mic(pyaudio_instance)
|
|
|
|
assert result is not None
|
|
assert result == default_mic
|