V3-07: route drawing (pins and straight lines)

Route plans are their own entity (RoutePlan/Waypoint, schema v3), never joined into ride totals or the rides list. RoutePlanRepository recomputes straight-line distance after every waypoint mutation. RoutePlannerScreen supports tap-to-add, tap-to-delete, and hand-rolled drag-to-move via MapCamera's screen/latlng conversions.

Fixed a real bug found by testing: FlutterMap's initialCenter/initialZoom are read once at construction, so building the map before the waypoints stream's first emission froze the camera on null-island. Also documents a genuine ten-minute test hang traced to Stream.first on a Drift watch() query inside testWidgets, which needs a pump-driven Timer that flutter_test's fake zone never advances on its own.
This commit is contained in:
2026-08-17 19:15:18 -05:00
parent 5013b7002f
commit a14f5b0134
15 changed files with 2694 additions and 5 deletions

View File

@@ -147,4 +147,34 @@ void main() {
expect(all.length, 3);
expect(all.every((t) => t.activity == Activity.motorcycle), isTrue);
});
test('a v2 database (V3-07) gains route_plans/waypoints and keeps its trips',
() async {
// v2: identical to the v1 seed above, plus the `activity` column V3-01 added.
seedV1Database();
final raw = sqlite3.sqlite3.open(dbFile.path);
raw.execute('''
ALTER TABLE trips ADD COLUMN activity TEXT NOT NULL DEFAULT 'motorcycle';
''');
raw.execute('PRAGMA user_version = 2;');
raw.close();
final db = AppDatabase(NativeDatabase(dbFile));
addTearDown(db.close);
// The pre-existing ride is untouched by an upgrade that has nothing to do with it.
final trip = await db.getTrip(1);
expect(trip, isNotNull);
expect(trip!.name, 'Old ride');
// The new tables are not just present but usable.
final routeId = await db.insertRoutePlan(
const RoutePlan(name: 'Coast loop', createdAt: 9000),
);
await db.insertWaypoint(
Waypoint(routeId: routeId, ordinal: 0, latitude: 51.0, longitude: -114.0),
);
final waypoints = await db.waypointsForRoute(routeId);
expect(waypoints, hasLength(1));
});
}