zonza/tests/test_garde_transcription.py
Ralph Mayola 68e1f336c8 Le peripherique audio ne peut plus geler l'interface
Le halo s'est fige une seconde fois, bloque sur « Je vous ecoute… », forme d'onde
plate, process a 0 % CPU. Une autre application (Loom) tenait le micro : le
stream.stop() de PortAudio s'est bloque. Or toggle() s'executait sur le thread
principal Cocoa — toute l'interface a gele avec lui.

Et le garde-fou pose le matin meme etait inoperant PAR CONSTRUCTION : c'est un
NSTimer, il vit sur la boucle d'evenements que le blocage venait justement d'arreter.
Un garde-fou qui depend de ce qu'il est cense sauver ne sauve rien.

Desormais, le chemin appele depuis le thread principal ne touche PLUS JAMAIS au
peripherique : ouverture et fermeture du flux partent en tache de fond, le thread
principal ne fait que changer l'etat et rafraichir l'overlay. Deux tests verrouillent
la regle avec un recorder qui leve si on l'appelle depuis le mauvais endroit.

S'ajoute une garde COURTE (20 s) armee des l'arret : passe ce point il ne reste que
la transcription, quelques secondes ; laisser 210 s de halo, c'est « fige » pour
l'utilisateur meme si le code finit par se rattraper.

Prouve en reproduisant la panne — un stop() qui ne rend jamais la main : l'interface
continue de battre (6, 12, 24 battements) et le halo se ferme seul. Avant, le
compteur serait reste fige.

69 tests passent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 12:14:47 +02:00

48 lines
1.6 KiB
Python

"""Deux gardes distinctes selon la phase.
Le halo s'est fige a l'ecran une seconde fois. La garde posee ce matin est reglee
sur le PIRE cas — un enregistrement de 2 min suivi de sa transcription — soit 210 s.
Trois minutes et demie de halo, c'est fige du point de vue de l'utilisateur, meme si
le code finit par se rattraper.
D'ou une garde COURTE des l'arret de l'enregistrement : a ce moment il ne reste que
la transcription, qui se compte en secondes. La garde longue ne couvre plus que la
phase d'enregistrement.
"""
import pytest
from core import CONFIG, validate_config
def test_les_deux_gardes_existent():
assert CONFIG["duree_max_overlay_s"] > 0
assert CONFIG["duree_max_transcription_s"] > 0
def test_la_garde_de_transcription_est_bien_plus_courte():
assert CONFIG["duree_max_transcription_s"] < CONFIG["duree_max_overlay_s"]
def test_elle_laisse_le_temps_de_transcrire():
# une transcription reelle prend 1 a 3 s ; en dessous de 10 s on couperait du travail
assert CONFIG["duree_max_transcription_s"] >= 10.0
def test_elle_reste_courte_pour_l_utilisateur():
# au-dela de 30 s, l'utilisateur parle de nouveau de « fige »
assert CONFIG["duree_max_transcription_s"] <= 30.0
def test_validate_config_refuse_une_garde_de_transcription_trop_courte():
with pytest.raises(ValueError):
validate_config(dict(CONFIG, duree_max_transcription_s=2.0))
def test_validate_config_refuse_une_garde_plus_longue_que_la_globale():
with pytest.raises(ValueError):
validate_config(dict(CONFIG, duree_max_transcription_s=CONFIG["duree_max_overlay_s"] + 1))
def test_la_config_livree_reste_valide():
validate_config(CONFIG)