import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:pluriwave/servicios/arranque_audio.dart'; /// S8-android-auto-cold-start: covers [esperarArranqueAudio]'s timeout race /// in isolation, without touching the real `audio_service` plugin (Design /// "Testability" — the init future is injected). void main() { group('esperarArranqueAudio', () { test( 'handler resuelto antes del timeout devuelve ArranqueAudioListo', () async { final resultado = await esperarArranqueAudio( Future.value('handler-ok'), timeout: const Duration(milliseconds: 200), ); expect(resultado, isA>()); expect((resultado as ArranqueAudioListo).handler, 'handler-ok'); }, ); test('handler colgado mas alla del timeout devuelve ArranqueAudioPendiente ' 'con el MISMO future original', () async { final completer = Completer(); final resultado = await esperarArranqueAudio( completer.future, timeout: const Duration(milliseconds: 20), ); expect(resultado, isA>()); expect( identical( (resultado as ArranqueAudioPendiente).handlerFuturo, completer.future, ), isTrue, reason: 'init nunca debe llamarse dos veces — el future pendiente ' 'debe ser exactamente el mismo objeto', ); // El completer nunca se completó — liberarlo evita un future // colgado tras el test. completer.complete('handler-tardio'); }); test('finalizacion tardia tras el timeout resuelve el future original con ' 'el handler real', () async { final completer = Completer(); final resultado = await esperarArranqueAudio( completer.future, timeout: const Duration(milliseconds: 20), ); final pendiente = resultado as ArranqueAudioPendiente; completer.complete('handler-tardio'); final handler = await pendiente.handlerFuturo; expect(handler, 'handler-tardio'); }); }); }