feat: add inserter module with clipboard paste and restore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-06 20:28:18 +02:00
parent 0e9db0b60e
commit 70d2b6d6e4
2 changed files with 114 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
import asyncio
from unittest.mock import AsyncMock, MagicMock, patch, call
import pytest
from whisper_local.inserter import Inserter
class TestInserter:
@pytest.mark.asyncio
@patch("whisper_local.inserter.asyncio.sleep", new_callable=AsyncMock)
@patch("whisper_local.inserter.asyncio.create_subprocess_exec")
async def test_insert_text_calls_tools_in_order(self, mock_exec, mock_sleep):
# Mock für alle subprocess-Aufrufe
mock_proc = AsyncMock()
mock_proc.communicate.return_value = (b"alter clipboard", b"")
mock_proc.returncode = 0
mock_exec.return_value = mock_proc
inserter = Inserter()
await inserter.insert("Hallo Welt")
# Prüfe dass wl-paste, wl-copy, wtype, wl-copy aufgerufen werden
calls = mock_exec.call_args_list
assert len(calls) == 4
assert calls[0][0][0] == "wl-paste" # Clipboard sichern
assert calls[1][0] == ("wl-copy", "Hallo Welt") # Text in Clipboard
assert calls[2][0][0] == "wtype" # Ctrl+V simulieren
assert calls[3][0] == ("wl-copy", "alter clipboard") # Clipboard wiederherstellen
@pytest.mark.asyncio
@patch("whisper_local.inserter.asyncio.create_subprocess_exec")
async def test_insert_empty_text_does_nothing(self, mock_exec):
inserter = Inserter()
await inserter.insert("")
mock_exec.assert_not_called()
@pytest.mark.asyncio
@patch("whisper_local.inserter.asyncio.sleep", new_callable=AsyncMock)
@patch("whisper_local.inserter.asyncio.create_subprocess_exec")
async def test_clipboard_restore_on_paste_failure(self, mock_exec, mock_sleep):
call_count = 0
async def mock_create_proc(*args, **kwargs):
nonlocal call_count
call_count += 1
mock_proc = AsyncMock()
if call_count == 1: # wl-paste
mock_proc.communicate.return_value = (b"original", b"")
mock_proc.returncode = 0
elif call_count == 2: # wl-copy
mock_proc.communicate.return_value = (b"", b"")
mock_proc.returncode = 0
elif call_count == 3: # wtype — fails
mock_proc.communicate.return_value = (b"", b"error")
mock_proc.returncode = 1
else: # wl-copy restore
mock_proc.communicate.return_value = (b"", b"")
mock_proc.returncode = 0
return mock_proc
mock_exec.side_effect = mock_create_proc
inserter = Inserter()
await inserter.insert("Test")
# Clipboard muss trotzdem wiederhergestellt werden
assert call_count == 4