MotorSignal-App/test/responsive_layout_test.dart

181 lines
6.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:motorcycle_dash/core/responsive/viewport_size.dart';
import 'package:motorcycle_dash/core/responsive/responsive_layout.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('ResponsiveBreakpoints & ResponsiveSnapshot Classification', () {
test('Classifies compact width (< 600dp) correctly', () {
final snap320 = ResponsiveSnapshot.fromDimensions(width: 320, height: 640);
expect(snap320.sizeClass, WindowSizeClass.compact);
expect(snap320.isCompact, isTrue);
expect(snap320.isMedium, isFalse);
expect(snap320.isExpanded, isFalse);
expect(snap320.isShortViewport, isFalse);
expect(snap320.useNavigationRail, isFalse);
final snap400 = ResponsiveSnapshot.fromDimensions(width: 400, height: 800);
expect(snap400.sizeClass, WindowSizeClass.compact);
expect(snap400.isCompact, isTrue);
final snap599 = ResponsiveSnapshot.fromDimensions(width: 599.9, height: 800);
expect(snap599.sizeClass, WindowSizeClass.compact);
});
test('Classifies medium width (600dp - 840dp) correctly', () {
final snap600 = ResponsiveSnapshot.fromDimensions(width: 600, height: 900);
expect(snap600.sizeClass, WindowSizeClass.medium);
expect(snap600.isCompact, isFalse);
expect(snap600.isMedium, isTrue);
expect(snap600.isExpanded, isFalse);
expect(snap600.useNavigationRail, isTrue);
final snap840 = ResponsiveSnapshot.fromDimensions(width: 840, height: 600);
expect(snap840.sizeClass, WindowSizeClass.medium);
expect(snap840.isMedium, isTrue);
expect(snap840.useNavigationRail, isTrue);
});
test('Classifies expanded width (> 840dp) correctly', () {
final snap841 = ResponsiveSnapshot.fromDimensions(width: 841, height: 600);
expect(snap841.sizeClass, WindowSizeClass.expanded);
expect(snap841.isCompact, isFalse);
expect(snap841.isMedium, isFalse);
expect(snap841.isExpanded, isTrue);
expect(snap841.useNavigationRail, isTrue);
final snap1200 = ResponsiveSnapshot.fromDimensions(width: 1200, height: 800);
expect(snap1200.sizeClass, WindowSizeClass.expanded);
});
test('Classifies short viewports (< 420dp height) for motorcycle mounts', () {
final mount800x360 = ResponsiveSnapshot.fromDimensions(width: 800, height: 360);
expect(mount800x360.isShortViewport, isTrue);
expect(mount800x360.useNavigationRail, isTrue);
final mount780x360 = ResponsiveSnapshot.fromDimensions(width: 780, height: 360);
expect(mount780x360.isShortViewport, isTrue);
expect(mount780x360.useNavigationRail, isTrue);
final mount840x390 = ResponsiveSnapshot.fromDimensions(width: 840, height: 390);
expect(mount840x390.isShortViewport, isTrue);
expect(mount840x390.useNavigationRail, isTrue);
final smallLandscape = ResponsiveSnapshot.fromDimensions(width: 500, height: 320);
expect(smallLandscape.sizeClass, WindowSizeClass.compact);
expect(smallLandscape.isShortViewport, isTrue);
expect(smallLandscape.useNavigationRail, isTrue);
});
test('BoxConstraints and MediaQuery factory constructors produce consistent snapshots', () {
const constraints = BoxConstraints(maxWidth: 720, maxHeight: 400);
final fromConstraints = ResponsiveSnapshot.fromConstraints(constraints);
expect(fromConstraints.width, 720);
expect(fromConstraints.height, 400);
expect(fromConstraints.sizeClass, WindowSizeClass.medium);
expect(fromConstraints.isShortViewport, isTrue);
const mediaQuery = MediaQueryData(size: Size(412, 915));
final fromMq = ResponsiveSnapshot.fromMediaQuery(mediaQuery);
expect(fromMq.width, 412);
expect(fromMq.height, 915);
expect(fromMq.sizeClass, WindowSizeClass.compact);
expect(fromMq.isShortViewport, isFalse);
});
});
group('ResponsiveLayout Declarative Widget', () {
testWidgets('Builds compact, medium, expanded, or shortViewport builders', (tester) async {
// 1. Compact
tester.view.physicalSize = const Size(360, 640);
tester.view.devicePixelRatio = 1.0;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: ResponsiveLayout(
compact: (_) => const Text('Compact View'),
medium: (_) => const Text('Medium View'),
expanded: (_) => const Text('Expanded View'),
),
),
),
);
expect(find.text('Compact View'), findsOneWidget);
// 2. Medium
tester.view.physicalSize = const Size(700, 640);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: ResponsiveLayout(
compact: (_) => const Text('Compact View'),
medium: (_) => const Text('Medium View'),
expanded: (_) => const Text('Expanded View'),
),
),
),
);
expect(find.text('Medium View'), findsOneWidget);
// 3. Expanded
tester.view.physicalSize = const Size(1200, 800);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: ResponsiveLayout(
compact: (_) => const Text('Compact View'),
medium: (_) => const Text('Medium View'),
expanded: (_) => const Text('Expanded View'),
),
),
),
);
expect(find.text('Expanded View'), findsOneWidget);
// 4. Short Viewport
tester.view.physicalSize = const Size(800, 360);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: ResponsiveLayout(
compact: (_) => const Text('Compact View'),
shortViewport: (_) => const Text('Short View'),
),
),
),
);
expect(find.text('Short View'), findsOneWidget);
});
testWidgets('General builder receives computed ResponsiveSnapshot', (tester) async {
tester.view.physicalSize = const Size(800, 360);
tester.view.devicePixelRatio = 1.0;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
ResponsiveSnapshot? captured;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: ResponsiveLayout(
builder: (context, snapshot) {
captured = snapshot;
return Text('Size: ${snapshot.sizeClass.name}');
},
),
),
),
);
expect(find.text('Size: medium'), findsOneWidget);
expect(captured?.isShortViewport, isTrue);
expect(captured?.useNavigationRail, isTrue);
});
});
}