import 'package:cardash_launcher/core/theme/app_theme.dart'; import 'package:cardash_launcher/features/home/widgets/shortcut_grid.dart'; import 'package:cardash_launcher/features/home/widgets/shortcut_tile.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; List _specs(int count) { return List.generate( count, (index) => ShortcutSpec( title: 'App $index', subtitle: index < 5 ? 'Select app' : null, iconAsset: 'assets/icons/app-window.svg', assigned: true, onTap: () {}, onLongPress: () {}, longPressHint: 'remove from Home', ), ); } Future _pumpGrid( WidgetTester tester, { required Size size, required bool compact, int count = 16, }) async { await tester.pumpWidget( MaterialApp( theme: AppTheme.light(), home: Scaffold( body: Center( child: SizedBox( width: size.width, height: size.height, child: ShortcutGrid(shortcuts: _specs(count), compact: compact), ), ), ), ), ); await tester.pump(); } void main() { TestWidgetsFlutterBinding.ensureInitialized(); testWidgets('16 buttons fit at 1280x800 without overflow', (tester) async { await _pumpGrid(tester, size: const Size(700, 610), compact: false); expect(tester.takeException(), isNull); expect(find.byType(ShortcutTile), findsNWidgets(16)); final first = tester.widget(find.byType(ShortcutTile).first); expect(first.size, lessThanOrEqualTo(196)); expect(first.size, greaterThan(64)); }); testWidgets('16 buttons fit at the 1280x720 layout', (tester) async { await _pumpGrid(tester, size: const Size(755, 500), compact: false); expect(tester.takeException(), isNull); expect(find.byType(ShortcutTile), findsNWidgets(16)); final first = tester.widget(find.byType(ShortcutTile).first); expect(first.size, lessThanOrEqualTo(196)); expect(first.size, greaterThan(64)); }); testWidgets('16 buttons fit at the 1024x600 compact layout', (tester) async { await _pumpGrid(tester, size: const Size(559, 476), compact: true); expect(tester.takeException(), isNull); expect(find.byType(ShortcutTile), findsNWidgets(16)); final first = tester.widget(find.byType(ShortcutTile).first); expect(first.size, lessThanOrEqualTo(168)); expect(first.size, greaterThan(64)); }); testWidgets('a short grid is anchored to the bottom edge', (tester) async { await _pumpGrid( tester, size: const Size(600, 400), compact: false, count: 4, ); expect(tester.takeException(), isNull); final grid = tester.getRect(find.byType(ShortcutGrid)); final wrap = tester.getRect(find.byType(Wrap)); final last = tester.getRect(find.byType(ShortcutTile).last); expect(last.bottom, moreOrLessEquals(grid.bottom, epsilon: 0.5)); expect(wrap.center.dx, moreOrLessEquals(grid.center.dx, epsilon: 0.5)); }); testWidgets('a long Jellyfin subtitle is clipped to the tile width', ( tester, ) async { await tester.binding.setSurfaceSize(const Size(1280, 400)); addTearDown(() => tester.binding.setSurfaceSize(null)); await tester.pumpWidget( MaterialApp( theme: AppTheme.light(), home: Scaffold( body: Center( child: ShortcutTile( title: 'Jellyfin', subtitle: 'Paradise Lost — Drown In Darkness - The Early Demos', iconAsset: 'assets/icons/headphones.svg', size: 196, assigned: true, onTap: () {}, ), ), ), ), ); await tester.pump(); expect(tester.getSize(find.byType(ShortcutTile)).width, 196); expect(tester.takeException(), isNull); }); }