diff --git a/lib/pantallas/pantalla_alarmas.dart b/lib/pantallas/pantalla_alarmas.dart index 86a591b..a879918 100644 --- a/lib/pantallas/pantalla_alarmas.dart +++ b/lib/pantallas/pantalla_alarmas.dart @@ -63,7 +63,14 @@ class PantallaAlarmas extends StatelessWidget { else for (final alarma in estado.alarmas) ...[ _TarjetaAlarma(alarma: alarma), - const SizedBox(height: 12), + // 7.5 (Tier 4 visual fidelity): the prototype's gap + // between stacked alarm cards is 10px (t4 line 334), + // not 12. Keyed per alarm id so the guard test can + // target the exact gap between two known cards. + SizedBox( + height: 10, + key: ValueKey('alarm-card-gap-${alarma.id}'), + ), ], _PanelVacaciones(estado: estado), const SizedBox(height: 12), diff --git a/test/pantallas/pantalla_alarmas_card_gap_test.dart b/test/pantallas/pantalla_alarmas_card_gap_test.dart new file mode 100644 index 0000000..ca52012 --- /dev/null +++ b/test/pantallas/pantalla_alarmas_card_gap_test.dart @@ -0,0 +1,90 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pluriwave/estado/estado_alarmas.dart'; +import 'package:pluriwave/estado/estado_radio.dart'; +import 'package:pluriwave/l10n/gen/app_localizations.dart'; +import 'package:pluriwave/modelos/alarma_musical.dart'; +import 'package:pluriwave/pantallas/pantalla_alarmas.dart'; +import 'package:pluriwave/servicios/servicio_alarmas.dart'; +import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../helpers/fakes.dart'; +import '../helpers/fakes_alarmas.dart'; + +/// Audit 7.5 (Tier 4 visual fidelity): the prototype's gap between stacked +/// alarm cards is 10px (t4 line 334, `gap:10` on the alarms column), not the +/// build's previous 12px. +void main() { + setUp(() { + SharedPreferences.setMockInitialValues({}); + }); + + testWidgets('spaces stacked alarm cards 10px apart, not 12', (tester) async { + tester.view.physicalSize = const Size(1440, 3200); + tester.view.devicePixelRatio = 1.0; + addTearDown(tester.view.resetPhysicalSize); + addTearDown(tester.view.resetDevicePixelRatio); + + final radio = EstadoRadio( + audio: FakeServicioAudio(), + favoritos: FakeServicioFavoritos(), + radio: FakeServicioRadio(), + servicioEcualizador: FakeServicioEcualizador(), + servicioGrabacion: FakeServicioGrabacionRadioInactiva(), + iniciarAutomaticamente: false, + ); + addTearDown(radio.dispose); + + final android = FakePuertoAlarmasAndroid(); + final estadoAlarmas = EstadoAlarmas( + servicio: ServicioAlarmas(reloj: () => DateTime(2026, 6, 11, 6, 0)), + android: android, + iniciarAutomaticamente: false, + ); + addTearDown(estadoAlarmas.dispose); + addTearDown(android.dispose); + await estadoAlarmas.guardarAlarma( + const AlarmaMusical( + id: 'card-gap-a', + nombre: 'Primera', + hora: 7, + minuto: 0, + tipoProgramacion: TipoProgramacionAlarma.diaria, + diasSemana: [], + ), + ); + await estadoAlarmas.guardarAlarma( + const AlarmaMusical( + id: 'card-gap-b', + nombre: 'Segunda', + hora: 8, + minuto: 0, + tipoProgramacion: TipoProgramacionAlarma.diaria, + diasSemana: [], + ), + ); + + await tester.pumpWidget( + MultiProvider( + providers: [ + ChangeNotifierProvider.value(value: radio), + ChangeNotifierProvider.value(value: estadoAlarmas), + ], + child: MaterialApp( + locale: const Locale('es'), + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + home: const Scaffold(body: PantallaAlarmas()), + ), + ), + ); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 100)); + + final gap = tester.widget( + find.byKey(const ValueKey('alarm-card-gap-card-gap-a')), + ); + expect(gap.height, 10); + }); +}