T19/T21: map and export, completing Phase 4
flutter_map with the same OSM tiles and no-API-key reasoning that chose osmdroid. All four load-bearing behaviours ported and, unlike the native app's map, tested: one polyline per segment so a pause is a real gap, render-only decimation, the zoom clamp at OSM's max tile zoom with a short-ride fallback, and a real user agent. Speed colouring is bucketed per run rather than per-vertex, since neither osmdroid nor flutter_map makes per-vertex paint reasonable. Export via share_plus, which also handles the iPad popover anchor a naive port forgets. It passes the raw stored points, never the map's decimated path. 164 tests passing, analyze clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -66,10 +66,13 @@ void main() {
|
||||
///
|
||||
/// The theme is deliberately included: the black-on-black bug was invisible to logic
|
||||
/// tests and only a rendered widget can catch its equivalent.
|
||||
Widget host(Widget child) => ProviderScope(
|
||||
Widget host(Widget child, {bool map = true}) => ProviderScope(
|
||||
overrides: [
|
||||
databaseProvider.overrideWithValue(db),
|
||||
locationSourceProvider.overrideWithValue(source),
|
||||
// The map is off by default in tests that are not about the map: it fetches
|
||||
// tiles, which a widget test cannot serve, and it changes scroll geometry.
|
||||
mapEnabledProvider.overrideWith((ref) => map),
|
||||
],
|
||||
child: MaterialApp(theme: ripprTheme(), home: child),
|
||||
);
|
||||
@@ -286,7 +289,7 @@ void main() {
|
||||
final id = await seedCompletedTrip(
|
||||
startedAt: 1000, endedAt: 5000, name: 'Sunday blast', points: 11);
|
||||
|
||||
await tester.pumpWidget(host(TripDetailScreen(tripId: id)));
|
||||
await tester.pumpWidget(host(TripDetailScreen(tripId: id), map: false));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Sunday blast'), findsOneWidget);
|
||||
@@ -297,7 +300,7 @@ void main() {
|
||||
|
||||
screenTest('a missing ride says so instead of rendering blank',
|
||||
(tester) async {
|
||||
await tester.pumpWidget(host(const TripDetailScreen(tripId: 9999)));
|
||||
await tester.pumpWidget(host(const TripDetailScreen(tripId: 9999), map: false));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.textContaining('no longer exists'), findsOneWidget);
|
||||
@@ -307,7 +310,7 @@ void main() {
|
||||
final id = await seedCompletedTrip(
|
||||
startedAt: 1000, endedAt: 2000, points: 1);
|
||||
|
||||
await tester.pumpWidget(host(TripDetailScreen(tripId: id)));
|
||||
await tester.pumpWidget(host(TripDetailScreen(tripId: id), map: false));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Both charts need intervals; one point has none. An unexplained blank box would
|
||||
@@ -325,7 +328,7 @@ void main() {
|
||||
screenTest('renaming updates the title', (tester) async {
|
||||
final id = await seedCompletedTrip(startedAt: 1000, endedAt: 5000);
|
||||
|
||||
await tester.pumpWidget(host(TripDetailScreen(tripId: id)));
|
||||
await tester.pumpWidget(host(TripDetailScreen(tripId: id), map: false));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byKey(const Key('rename')));
|
||||
|
||||
Reference in New Issue
Block a user