import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:miler/data/service_profile.dart'; import 'package:miler/views/Dashboard/home/route_timeline.dart'; import 'package:miler/views/Dashboard/home/trip.dart'; import 'package:miler/views/Dashboard/home/trip_card.dart'; import 'package:miler/views/helpers/constants/Colorconstants.dart'; /// ───────────────────────────────────────────────────────────────────────── /// ONE GRID, MEASURED /// /// Home is read by running the eye down two columns: names on the left, bags /// and figures on the right. Every point of drift in either costs a fixation, /// and drift is invisible in code review — it comes from nested padding that /// each looks correct where it is written. /// /// The select-all was 36pt off the name axis, because the row is railed by its /// caller *and* reserved a second rail inside the widget: two corrections for /// one indent. Then it was 2pt off, because the rail it sits in is 2 wider /// than the order rows' own. Both were found by measuring, not by reading. /// ───────────────────────────────────────────────────────────────────────── void main() { tearDown(() => ServiceProfile.setActive(ServiceProfile.parcel)); Map meal(String id, String who, {int step = 1}) => { 'orderid': id, 'type': 'delivery', 'step': step, 'pickupcustomer': who, 'kitchenid': 'K1', 'kitchenname': 'Vidhya Kitchen', 'sourcename': 'Vidhya Kitchen', 'pickupcontactno': '9787698259', 'pickupaddress': '4 Cross, RS Puram, Coimbatore', 'dropaddress': '12 SNS Colony, Peelamedu, Coimbatore 641004', 'Quantity': '1', }; Future pumpHome( WidgetTester tester, { double width = 390, double textScale = 1.0, int orders = 3, }) async { ServiceProfile.setActive(ServiceProfile.milkMan); // A real phone's geometry. A taller view with the same design size scales // every `.h` by the ratio and makes every measurement here a fiction — // which is exactly how a "116dp row" was once reported on a 62dp row. tester.view.physicalSize = Size(width * 3, 844 * 3); tester.view.devicePixelRatio = 3.0; addTearDown(tester.view.reset); final trip = Trip.fromStops( id: 'run', stops: [ for (var i = 1; i <= orders; i++) meal('$i', 'Customer $i', step: i), ], ); await tester.pumpWidget( ScreenUtilInit( designSize: const Size(390, 844), builder: (_, _) => MaterialApp( builder: (context, child) => MediaQuery( data: MediaQuery.of( context, ).copyWith(textScaler: TextScaler.linear(textScale)), child: child!, ), home: Scaffold( backgroundColor: ColorConstants.daylightSurface, body: SingleChildScrollView( child: TripCard( trip: trip, onToggleSelect: (_) {}, onSelectAll: (_) {}, onStopTap: (_) {}, onCallStop: (_) {}, ), ), ), ), ), ); await tester.pumpAndSettle(); } group('the two columns', () { testWidgets('every customer name starts on one axis', (tester) async { await pumpHome(tester, orders: 4); final lefts = [ for (var i = 1; i <= 4; i++) tester.getRect(find.text('Customer $i')).left, ]; for (final l in lefts) { expect(l, closeTo(lefts.first, 0.5)); } }); testWidgets('every Bag ends on one axis', (tester) async { await pumpHome(tester, orders: 4); final rights = [ for (var i = 1; i <= 4; i++) tester.getRect(find.text('Bag $i')).right, ]; for (final r in rights) { expect(r, closeTo(rights.first, 0.5)); } }); testWidgets('the select-all label sits on the name axis', (tester) async { await pumpHome(tester); // The regression this file exists for. It heads the list it selects, so // it starts where the list starts — not one rail further in, and not two // points off it either. final label = tester.getRect(find.text('Select all 3')).left; final name = tester.getRect(find.text('Customer 1')).left; expect( label, closeTo(name, 0.5), reason: 'the select-all is $label, the names are $name', ); }); testWidgets('the kitchen and its state share one axis', (tester) async { await pumpHome(tester); expect( tester.getRect(find.text('Pending')).left, closeTo(tester.getRect(find.text('Vidhya Kitchen')).left, 0.5), ); }); }); group('type ranks the page', () { testWidgets('the kitchen outranks the customer, which outranks the area', ( tester, ) async { await pumpHome(tester); final kitchen = tester.widget(find.text('Vidhya Kitchen')).style!; final name = tester.widget(find.text('Customer 1')).style!; final area = tester.widget(find.text('Peelamedu').first).style!; expect(kitchen.fontSize, 19); expect(kitchen.fontWeight, FontWeight.w700); expect(name.fontSize, 15); expect(area.fontSize, 12.5); // A customer row must never overpower the heading it sits under. expect(name.fontSize!, lessThan(kitchen.fontSize!)); expect(area.fontSize!, lessThan(name.fontSize!)); expect(area.fontSize!, greaterThanOrEqualTo(12)); }); }); group('rows grow, they do not clip', () { for (final (width, scale) in const [ (390.0, 1.0), (390.0, 2.0), (375.0, 1.0), (375.0, 2.0), (320.0, 1.0), (320.0, 2.0), ]) { testWidgets('${width.toInt()}px @ ${scale}x lays out clean', ( tester, ) async { await pumpHome(tester, width: width, textScale: scale, orders: 4); expect( tester.takeException(), isNull, reason: 'no overflow at ${width.toInt()}px / ${scale}x', ); }); } testWidgets('a one-line row clears the touch floor and grows at 2x', ( tester, ) async { await pumpHome(tester); final at1x = tester.getRect(find.byType(PickupTimelineStep).first).height; expect( at1x, greaterThanOrEqualTo(44), reason: 'a step is reachable with a gloved thumb', ); await pumpHome(tester, textScale: 2.0); final at2x = tester.getRect(find.byType(PickupTimelineStep).first).height; expect( at2x, greaterThan(at1x), reason: 'density comes from removing furniture, never from clipping', ); }); }); }