|
@@ -36,7 +36,8 @@ class VoiceTests(unittest.IsolatedAsyncioTestCase):
|
|
|
self.sink.queue.task_done()
|
|
self.sink.queue.task_done()
|
|
|
self.assertEqual(user.id, 1)
|
|
self.assertEqual(user.id, 1)
|
|
|
self.assertEqual(pcm, self.pcm)
|
|
self.assertEqual(pcm, self.pcm)
|
|
|
- self.assertIn(2, self.sink.buffers)
|
|
|
|
|
|
|
+ self.assertFalse(self.sink.buffers)
|
|
|
|
|
+ self.assertTrue(self.sink.busy)
|
|
|
|
|
|
|
|
async def test_audio_is_bounded_and_short_noise_ignored(self):
|
|
async def test_audio_is_bounded_and_short_noise_ignored(self):
|
|
|
self.sink.worker_task.cancel()
|
|
self.sink.worker_task.cancel()
|
|
@@ -72,6 +73,7 @@ class VoiceTests(unittest.IsolatedAsyncioTestCase):
|
|
|
with patch('voice_stt.httpx.AsyncClient', return_value=http):
|
|
with patch('voice_stt.httpx.AsyncClient', return_value=http):
|
|
|
self.sink = STTSink(self.reply, 'http://stt/transcribe')
|
|
self.sink = STTSink(self.reply, 'http://stt/transcribe')
|
|
|
self.sink.queue.put_nowait((self.user, self.pcm))
|
|
self.sink.queue.put_nowait((self.user, self.pcm))
|
|
|
|
|
+ await asyncio.wait_for(self.sink.queue.join(), 2)
|
|
|
self.sink.queue.put_nowait((self.user, self.pcm))
|
|
self.sink.queue.put_nowait((self.user, self.pcm))
|
|
|
await asyncio.wait_for(self.sink.queue.join(), 2)
|
|
await asyncio.wait_for(self.sink.queue.join(), 2)
|
|
|
self.reply.assert_awaited_once_with(self.user, 'Bonjour')
|
|
self.reply.assert_awaited_once_with(self.user, 'Bonjour')
|
|
@@ -80,6 +82,50 @@ class VoiceTests(unittest.IsolatedAsyncioTestCase):
|
|
|
self.assertEqual((wav.getnchannels(), wav.getsampwidth(), wav.getframerate()), (2, 2, 48000))
|
|
self.assertEqual((wav.getnchannels(), wav.getsampwidth(), wav.getframerate()), (2, 2, 48000))
|
|
|
self.assertEqual(wav.readframes(wav.getnframes()), self.pcm)
|
|
self.assertEqual(wav.readframes(wav.getnframes()), self.pcm)
|
|
|
|
|
|
|
|
|
|
+ async def test_no_backlog_during_stt_and_reply(self):
|
|
|
|
|
+ await self.sink.close()
|
|
|
|
|
+ stt_started, release_stt = asyncio.Event(), asyncio.Event()
|
|
|
|
|
+ reply_started, release_reply = asyncio.Event(), asyncio.Event()
|
|
|
|
|
+
|
|
|
|
|
+ async def post(*args, **kwargs):
|
|
|
|
|
+ stt_started.set()
|
|
|
|
|
+ await release_stt.wait()
|
|
|
|
|
+ return httpx.Response(200, json={'text': 'Bonjour'},
|
|
|
|
|
+ request=httpx.Request('POST', 'http://stt'))
|
|
|
|
|
+
|
|
|
|
|
+ async def reply(*args):
|
|
|
|
|
+ reply_started.set()
|
|
|
|
|
+ await release_reply.wait()
|
|
|
|
|
+
|
|
|
|
|
+ http = AsyncMock()
|
|
|
|
|
+ http.__aenter__.return_value.post.side_effect = post
|
|
|
|
|
+ self.reply.side_effect = reply
|
|
|
|
|
+ other = SimpleNamespace(id=2)
|
|
|
|
|
+ with patch('voice_stt.httpx.AsyncClient', return_value=http):
|
|
|
|
|
+ self.sink = STTSink(self.reply, 'http://stt/transcribe')
|
|
|
|
|
+ with self.sink.lock:
|
|
|
|
|
+ self.sink.add_pcm(self.user, self.pcm, time.monotonic() - 2)
|
|
|
|
|
+ self.sink.add_pcm(other, self.pcm, time.monotonic() - 2)
|
|
|
|
|
+ await asyncio.wait_for(stt_started.wait(), 2)
|
|
|
|
|
+ with self.sink.lock:
|
|
|
|
|
+ self.sink.add_pcm(other, self.pcm, time.monotonic())
|
|
|
|
|
+ release_stt.set()
|
|
|
|
|
+ await asyncio.wait_for(reply_started.wait(), 2)
|
|
|
|
|
+ with self.sink.lock:
|
|
|
|
|
+ self.sink.add_pcm(other, self.pcm, time.monotonic())
|
|
|
|
|
+ self.assertTrue(self.sink.queue.empty())
|
|
|
|
|
+ self.assertFalse(self.sink.buffers)
|
|
|
|
|
+ release_reply.set()
|
|
|
|
|
+ await asyncio.wait_for(self.sink.queue.join(), 2)
|
|
|
|
|
+ self.assertFalse(self.sink.busy)
|
|
|
|
|
+ self.reply.assert_awaited_once_with(self.user, 'Bonjour')
|
|
|
|
|
+ with self.sink.lock:
|
|
|
|
|
+ now = time.monotonic()
|
|
|
|
|
+ self.sink.add_pcm(other, self.pcm, now)
|
|
|
|
|
+ self.assertFalse(self.sink.buffers) # Ne pas récupérer la fin d'une phrase ignorée.
|
|
|
|
|
+ self.sink.add_pcm(other, self.pcm, now + 1)
|
|
|
|
|
+ self.assertIn(2, self.sink.buffers)
|
|
|
|
|
+
|
|
|
async def test_close_discards_pending_audio(self):
|
|
async def test_close_discards_pending_audio(self):
|
|
|
self.sink.queue.put_nowait((self.user, self.pcm))
|
|
self.sink.queue.put_nowait((self.user, self.pcm))
|
|
|
await self.sink.close()
|
|
await self.sink.close()
|
|
@@ -145,7 +191,7 @@ class CommandTests(unittest.IsolatedAsyncioTestCase):
|
|
|
voice_command_lock=asyncio.Lock(), httpx=SimpleNamespace(AsyncClient=Mock(return_value=http)),
|
|
voice_command_lock=asyncio.Lock(), httpx=SimpleNamespace(AsyncClient=Mock(return_value=http)),
|
|
|
voice_recv=SimpleNamespace(VoiceRecvClient=object), STTSink=make_sink,
|
|
voice_recv=SimpleNamespace(VoiceRecvClient=object), STTSink=make_sink,
|
|
|
call_openai_api=call_api, transform_emote=lambda text, output: text,
|
|
call_openai_api=call_api, transform_emote=lambda text, output: text,
|
|
|
- filter_message=lambda text: text, split_message=lambda text: [text],
|
|
|
|
|
|
|
+ filter_message=lambda text: text, split_message=lambda text, **kwargs: [text],
|
|
|
discord=discord, logger=Mock(),
|
|
discord=discord, logger=Mock(),
|
|
|
)
|
|
)
|
|
|
exec(compile(ast.Module(body=[function], type_ignores=[]), '<commands>', 'exec'), namespace)
|
|
exec(compile(ast.Module(body=[function], type_ignores=[]), '<commands>', 'exec'), namespace)
|
|
@@ -155,6 +201,9 @@ class CommandTests(unittest.IsolatedAsyncioTestCase):
|
|
|
await callback(SimpleNamespace(display_name='Alice'), 'Bonjour')
|
|
await callback(SimpleNamespace(display_name='Alice'), 'Bonjour')
|
|
|
call_api.assert_awaited_once_with('Bonjour', 'Alice')
|
|
call_api.assert_awaited_once_with('Bonjour', 'Alice')
|
|
|
self.assertEqual(message.channel.send.call_args.args[0], 'Réponse')
|
|
self.assertEqual(message.channel.send.call_args.args[0], 'Réponse')
|
|
|
|
|
+ quote = message.channel.send.call_args_list[-2]
|
|
|
|
|
+ self.assertEqual(quote.args[0], '> 🎙 Alice : Bonjour')
|
|
|
|
|
+ self.assertEqual(quote.kwargs['allowed_mentions'].to_dict(), {'parse': []})
|
|
|
message.content = '!quit'
|
|
message.content = '!quit'
|
|
|
message.guild.voice_client = voice
|
|
message.guild.voice_client = voice
|
|
|
await namespace['handle_voice_command'](message)
|
|
await namespace['handle_voice_command'](message)
|