Files
doormile_milderapp/test/trip_tabs_pinned_test.dart
2026-09-09 12:55:23 +05:30

205 lines
7.4 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:miler/views/Dashboard/home/trip.dart';
import 'package:miler/views/Dashboard/home/trip_tabs.dart';
/// ─────────────────────────────────────────────────────────────────────────
/// THE SELECTOR STAYS PUT, AND IT STAYS ONE HEIGHT
///
/// This file used to guard a pinned `SliverPersistentHeader`: the delegate had
/// to declare a fixed extent, [TripSelector]'s content was type that grows with
/// the system font, and the two disagreed by a few pixels at large settings —
/// so `extentFor` derived an over-estimate and these tests measured it from
/// 1.0× to 2.0× to prove it was never short.
///
/// **None of that exists any more.** The selector moved into the brand header,
/// which is fixed by being the Column's first child rather than by being a
/// sliver, so there is no extent to declare and nothing to under-estimate.
///
/// What survives is the property the arithmetic was protecting, and it is now
/// the widget's own: the control is a **fixed height** that does not move with
/// the text scale. A header that grows a few points at 1.5× pushes the whole
/// page down and re-lays the route out under the rider's thumb. It cannot,
/// because nothing in the control is free-flowing type — the numeral is inside
/// a `FittedBox` that scales it down into the space it has.
/// ─────────────────────────────────────────────────────────────────────────
void main() {
Map<String, dynamic> stop(String id) => {
'orderid': id,
'pickupid': id,
'pickupcustomer': 'Sri Balaji Stores',
'pickupaddress': '19, Thadagam Road, Coimbatore',
'orderstatus': 'pending',
};
Future<void> pump(
WidgetTester tester, {
required int trips,
int selected = 0,
double textScale = 1.0,
}) async {
tester.view.physicalSize = const Size(390 * 3, 844 * 3);
tester.view.devicePixelRatio = 3.0;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
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(
body: Padding(
padding: const EdgeInsets.all(16),
child: TripSelector(
trips: [
for (var i = 0; i < trips; i++)
Trip.fromStops(id: 't$i', stops: [stop('$i')]),
],
selectedIndex: selected,
onSelect: (_) {},
),
),
),
),
),
);
await tester.pump();
}
group('the control is one height at every text scale', () {
for (final scale in const [1.0, 1.3, 1.5, 2.0]) {
testWidgets('at ${scale}x', (tester) async {
await pump(tester, trips: 2, textScale: scale);
await tester.pump(const Duration(milliseconds: 400));
expect(
tester.getSize(find.byType(TripSelector)).height,
TripSelector.height,
reason:
'the header must not change height with the font, or the whole '
'route below it moves under the rider\'s thumb',
);
expect(tester.takeException(), isNull);
});
}
});
testWidgets('three slots render before the hub has filled them', (
tester,
) async {
await pump(tester, trips: 1);
for (final n in ['Trip 1', 'Trip 2', 'Trip 3']) {
expect(find.text(n), findsOneWidget);
}
});
testWidgets('exactly one segment is marked, and it is the selected one', (
tester,
) async {
await pump(tester, trips: 2, selected: 1);
await tester.pump(const Duration(milliseconds: 400));
final marks = find.byKey(TripSelector.markerKey);
expect(marks, findsOneWidget, reason: 'one trip is current, not two');
// The rule is a short centred mark under its pill rather than a full-width
// underline, so what has to hold is that it is centred on the *right*
// pill — not that it spans it.
final marker = tester.getRect(marks);
final second = tester.getRect(find.text('Trip 2'));
expect(
marker.center.dx,
closeTo(second.center.dx, 6),
reason: 'the rule sits under the pill it belongs to',
);
expect(
marker.top,
greaterThan(second.bottom),
reason: 'and under it, not through it',
);
});
testWidgets('the indicator is a rule, not a filled tab', (tester) async {
// The tabs sit straight on the brand ground: no card, no wash, no outline.
// Selection is the travelling rule and the ink weight, and nothing else.
await pump(tester, trips: 2);
await tester.pump(const Duration(milliseconds: 400));
final marker = tester.getSize(find.byKey(TripSelector.markerKey));
expect(
marker.height,
lessThanOrEqualTo(4),
reason: 'a 2-3dp rule, not a segment-sized fill',
);
});
testWidgets('a segment is tappable and reports its own index', (
tester,
) async {
int? chosen;
tester.view.physicalSize = const Size(390 * 3, 844 * 3);
tester.view.devicePixelRatio = 3.0;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await tester.pumpWidget(
ScreenUtilInit(
designSize: const Size(390, 844),
builder: (_, _) => MaterialApp(
home: Scaffold(
body: Padding(
padding: const EdgeInsets.all(16),
child: TripSelector(
trips: [
Trip.fromStops(id: 't0', stops: [stop('0')]),
Trip.fromStops(id: 't1', stops: [stop('1')]),
],
selectedIndex: 0,
onSelect: (i) => chosen = i,
),
),
),
),
),
);
await tester.pump();
await tester.tap(find.text('Trip 2'));
expect(chosen, 1);
});
// ── What the panel holds when a slot is empty ──
//
// Nothing, as far as this control is concerned. [TripSelector] draws the tab
// strip and whatever body it is handed; Home hands it the selected trip's
// brief, and for a slot the hub has not filled that is the *same* brief built
// from an empty trip — `0 stops left` and an em dash under every figure. See
// `trip_unassigned_brief_test.dart`.
//
// So there is no "empty" state in here to test, and nothing in this control
// says `Not assigned yet` any more: that line made the panel a stub under a
// tab twice its height, and repeated a sentence the empty state below already
// carried.
group('with no body', () {
testWidgets('the control is just the tab strip', (tester) async {
await pump(tester, trips: 1, selected: 2);
expect(find.text('Not assigned yet'), findsNothing);
expect(
tester.getSize(find.byType(TripSelector)).height,
TripSelector.height,
);
expect(tester.takeException(), isNull);
});
});
}