"""Verifies the Clap Detection Settings dialog: defaults match clap_detection.py's DEFAULT_THRESHOLD/DEFAULT_MIN_INTERVAL, changing values and accepting actually updates MainWindow state and gets used by the next detection run, Cancel leaves state untouched, and Reset to Defaults in the dialog restores the shared constants (not just whatever MainWindow happened to start with). """ import sys import time from pathlib import Path from PyQt6.QtWidgets import QApplication, QDialog sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) import main as app_main from clap_detection import DEFAULT_THRESHOLD, DEFAULT_MIN_INTERVAL ROOT = Path(__file__).resolve().parent.parent CLIP = str(ROOT / "test_media" / "sync_test_INSYNC.mp4") def wait_for(predicate, qapp, timeout=20): deadline = time.time() + timeout while not predicate() and time.time() < deadline: qapp.processEvents() time.sleep(0.05) return predicate() def main(): qapp = QApplication(sys.argv) win = app_main.MainWindow() win.show() qapp.processEvents() assert win.clap_threshold == DEFAULT_THRESHOLD assert win.clap_min_interval == DEFAULT_MIN_INTERVAL print(f"PASS: MainWindow starts with defaults ({DEFAULT_THRESHOLD}, {DEFAULT_MIN_INTERVAL})") # -- Dialog opens pre-filled with current settings dialog = app_main.ClapSettingsDialog(win.clap_threshold, win.clap_min_interval) assert dialog.threshold_spin.value() == DEFAULT_THRESHOLD assert dialog.min_interval_spin.value() == DEFAULT_MIN_INTERVAL # -- Changing values and cancelling shouldn't touch MainWindow state dialog.threshold_spin.setValue(0.3) dialog.min_interval_spin.setValue(1.5) dialog.reject() assert win.clap_threshold == DEFAULT_THRESHOLD, "cancel should not have changed MainWindow state" print("PASS: Cancel leaves settings untouched") # -- Changing values and accepting (simulated via the real handler) does # update MainWindow state and gets used by the actual worker. dialog2 = app_main.ClapSettingsDialog(win.clap_threshold, win.clap_min_interval) dialog2.threshold_spin.setValue(0.3) # very sensitive dialog2.min_interval_spin.setValue(0.1) win.clap_threshold, win.clap_min_interval = dialog2.values() assert win.clap_threshold == 0.3 assert win.clap_min_interval == 0.1 print("PASS: Accepting new values updates MainWindow state") # -- Reset to Defaults button restores the shared constants regardless # of what was passed in (even if MainWindow itself had non-default # settings already). dialog3 = app_main.ClapSettingsDialog(0.3, 0.1) assert dialog3.threshold_spin.value() == 0.3 dialog3._reset_to_defaults() assert dialog3.threshold_spin.value() == DEFAULT_THRESHOLD assert dialog3.min_interval_spin.value() == DEFAULT_MIN_INTERVAL print("PASS: Reset to Defaults restores DEFAULT_THRESHOLD/DEFAULT_MIN_INTERVAL") # -- End-to-end: a changed (very sensitive) threshold actually reaches # the real DetectWorker/detect_claps() call for a real detection run. win._load(CLIP) qapp.processEvents() time.sleep(0.2) qapp.processEvents() win.clap_threshold = 0.3 win.clap_min_interval = 0.1 win.detect_all_button.click() qapp.processEvents() assert win._detect_worker.threshold == 0.3 assert win._detect_worker.min_interval == 0.1 ok = wait_for(lambda: win.detect_all_button.isEnabled(), qapp) assert ok, "detection did not finish in time" print("PASS: changed settings actually reach the DetectWorker for a real run") win.close() qapp.processEvents() print("\nCLAP SETTINGS SMOKE TEST PASSED") if __name__ == "__main__": main()