Files
doormile_milderapp/test/text_scale_sweep_test.dart
Thiru-tenext d7348e253f Miler rider app: surface system, visible design language, backend lifecycle
Design system
- MilerSurface ladder (canvas → working → raised → floating) with MilerPanel
  as layer 1; canvas moved to #DEE3EA so white separates at 1.290:1.
- Visible vocabulary applied across Home, Deliveries, Activity, Account and
  the sheets: hero heads (tabular numeral + small caption, clamped at 1.3x),
  canvas wells for anything that opens, small filled tags for shelf labels,
  demoted placeholders. Recorded in DESIGN_SYSTEM.md §6.
- One icon family: 222 Material glyphs migrated to Lucide; none left outside
  lib/xpress.
- Colour semantics corrected: amber only for what is genuinely owed, brand red
  reserved for the live stop, disabled primaries go neutral rather than pale.

Data and lifecycle
- lib/data/lifecycle.dart reads mutations for what they prove; route_order.dart
  makes admin sequence the single ordering authority; service_day.dart, and
  stop_area.dart rewritten against live Coimbatore addresses (digit-token
  stripping, city stoplist, street suffixes, stammer collapse).
- countLabel states the load once, in bags.

Testing
- 1440 tests passing; golden shot harnesses for Home, Deliveries, Activity,
  sheets and verify, with test/failures/ now gitignored (diff debris).
- New pins: home_gutter_test, stop_area_test, plus updated structural bounds.

Note: this commit also carries pre-existing working-tree deletions that were
present before this work (API_SPEC.md, README.md, demo test fixtures).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 05:40:35 +05:30

109 lines
3.7 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:shared_preferences/shared_preferences.dart';
import 'package:miler/views/Dashboard/activity/activity_page.dart';
import 'package:miler/views/Dashboard/summary/summary.dart';
import 'package:miler/views/offline/offline_banner.dart';
/// ── Riders turn the system font up ──
///
/// An audit found the screens with layout tests (verify, collect payment,
/// profile, trip tabs) solid at 2×, and everything else unguarded: 443 `Text`
/// widgets against 109 `maxLines`, and exactly one file in 102 reading the text
/// scaler.
///
/// The failure mode is not cosmetic. A `Row` with a fixed-width child overflows
/// into the black-and-yellow stripe bar, which on a customer's doorstep looks
/// like the app has crashed. Earnings was the worst of them — a 46sp hero
/// figure sharing a row with labels — which is why that figure is now on the
/// type scale.
///
/// This sweeps the screens that had no coverage. It asserts no exception is
/// thrown, which is exactly what a `RenderFlex` overflow does.
void main() {
Future<void> pump(
WidgetTester tester,
Widget page, {
double width = 360,
double scale = 1.0,
}) async {
tester.view.physicalSize = Size(width * 3, 780 * 3);
tester.view.devicePixelRatio = 3.0;
addTearDown(tester.view.reset);
await tester.pumpWidget(
ScreenUtilInit(
designSize: const Size(390, 844),
minTextAdapt: true,
builder: (_, _) => MaterialApp(
builder: (context, child) => MediaQuery(
data: MediaQuery.of(
context,
).copyWith(textScaler: TextScaler.linear(scale)),
child: child!,
),
home: page,
),
),
);
await tester.pump(const Duration(milliseconds: 400));
}
// The four scales Android offers, on the narrowest phone the app supports.
const scales = [1.0, 1.3, 1.5, 2.0];
group('Earnings', () {
for (final s in scales) {
testWidgets('lays out at ${s}x', (tester) async {
SharedPreferences.setMockInitialValues({'userId': 1});
await pump(tester, const Summary(), scale: s);
expect(tester.takeException(), isNull);
});
}
});
group('Activity', () {
for (final s in scales) {
testWidgets('lays out at ${s}x', (tester) async {
SharedPreferences.setMockInitialValues({'userId': 1});
await pump(tester, const ActivityPage(), scale: s);
expect(tester.takeException(), isNull);
});
}
});
// ── Sign In is covered by `auth_design_test.dart`, not here ──
//
// The screen calls `NotificationServce.initialize` in `initState`, which
// needs a platform channel a widget test has no way to answer. That is a test
// harness limitation rather than a layout finding: the auth *components* —
// the code row, the scaffold, the primary button, the inline error — are
// pumped and asserted directly in `auth_design_test.dart`, which is where the
// design surface actually lives.
group('the offline strip', () {
for (final s in scales) {
testWidgets('lays out at ${s}x without covering the job', (tester) async {
await pump(
tester,
const OfflineScope(
offline: true,
child: Scaffold(
body: Center(child: Text('45, Lake View Apartments, Coimbatore')),
),
),
scale: s,
);
expect(tester.takeException(), isNull);
// Still readable, still not on top of anything.
expect(
find.text('45, Lake View Apartments, Coimbatore'),
findsOneWidget,
);
});
}
});
}