import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pluriwave/pantallas/ajustes/widgets/fila_ajuste.dart'; import 'package:pluriwave/tema/pluriwave_theme.dart'; /// S8 (Tier 1 visual fidelity): the prototype puts a trailing "current /// value" on nearly every settings row, 13px `rgba(242,247,250,.55)` (t4 /// lines 512-539, 625 — "Voz clara", "Alta", "3 guardados", "Alfabético", /// "7 · 84 MB", "Español", "Hoy, 08:12", "200 MB"). `FilaAjuste` used to /// accept only `icon`/`titulo`/`onTap` — no value slot at all. /// Pre-existing project constraint (see `pantalla_ajustes_test.dart`): /// `PluriGlassSurface` paints a background over `ListTile`'s ink layer, /// which Flutter flags as a warning-level assertion, not a correctness bug. /// Only needed by the `GrupoAjustes` test below — the bare `FilaAjuste` /// tests above never wrap a `ListTile` inside that surface. void _suppressListTileInkAssertion() { final original = FlutterError.onError; FlutterError.onError = (details) { if (details.exceptionAsString().contains( 'ListTile background color or ink splashes may be invisible', )) { return; } original?.call(details); }; addTearDown(() => FlutterError.onError = original); } void main() { Widget host(Widget child) { return MaterialApp( theme: PluriWaveTheme.dark(), home: Scaffold(body: child), ); } testWidgets('renders the trailing value before the chevron when provided', ( tester, ) async { await tester.pumpWidget( host( FilaAjuste( icon: Icons.language_rounded, titulo: 'Language', valor: 'English', onTap: () {}, ), ), ); expect(find.text('English'), findsOneWidget); expect(find.byIcon(Icons.chevron_right_rounded), findsOneWidget); }); testWidgets('renders no trailing value text when valor is omitted ' '(unchanged pre-S8 behaviour)', (tester) async { await tester.pumpWidget( host( FilaAjuste( icon: Icons.info_outline_rounded, titulo: 'Info', onTap: () {}, ), ), ); expect(find.text('Info'), findsOneWidget); expect(find.byIcon(Icons.chevron_right_rounded), findsOneWidget); }); testWidgets( 'visual fidelity (audit 10.6/10.8/10.9): leading icon is 21px, the ' 'title is 14px, and the chevron is 19px at 40% opacity (t4 lines ' '514-515)', (tester) async { await tester.pumpWidget( host( FilaAjuste( icon: Icons.equalizer_rounded, titulo: 'Ecualizador base', onTap: () {}, ), ), ); final icon = tester.widget(find.byIcon(Icons.equalizer_rounded)); expect(icon.size, 21); final titulo = tester.widget(find.text('Ecualizador base')); expect(titulo.style?.fontSize, 14); final chevron = tester.widget( find.byIcon(Icons.chevron_right_rounded), ); expect(chevron.size, 19); expect(chevron.color, const Color(0xFFF2F7FA).withValues(alpha: 0.4)); }, ); testWidgets( 'visual fidelity (audit S10): GrupoAjustes insets its row divider by ' '47px, not full-bleed (t4 line 516)', (tester) async { _suppressListTileInkAssertion(); await tester.pumpWidget( host( GrupoAjustes( titulo: 'AUDIO', filas: [ FilaAjuste( icon: Icons.equalizer_rounded, titulo: 'Uno', onTap: () {}, ), FilaAjuste(icon: Icons.hd_rounded, titulo: 'Dos', onTap: () {}), ], ), ), ); final divider = tester.widget(find.byType(Divider)); expect(divider.indent, 47); }, ); }