feat(train): a route's line pulled out into a new waypoint, and any waypoint taken off (ADR 0030, D59)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-30 23:01:04 +01:00
commit 57262ebf73
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
2 changed files with 371 additions and 36 deletions

View file

@ -168,6 +168,29 @@ void main() {
await cubit.close();
});
test('a waypoint pulled out of the line goes between the two around it, '
'and any one is taken off (D59)', () async {
final cubit = editor();
await cubit.open();
await cubit.add(home);
await cubit.add(river);
await cubit.insert(1, park);
expect(cubit.state.route.waypoints, [home, park, river]);
expect(routing.asked.last.waypoints, [home, park, river]);
expect(cubit.state.route.planned, straightRoute(const [home, park, river]));
await cubit.remove(0);
expect(cubit.state.route.waypoints, [park, river]);
expect(routing.asked.last.waypoints, [park, river]);
await cubit.remove(1);
expect(cubit.state.route.waypoints, [park]);
expect(cubit.state.route.planned, isNull);
expect(routing.asked, hasLength(3));
await cubit.close();
});
test('the activity picks its profile, which the person can change and '
'which plans again', () async {
final cubit = editor();

View file

@ -0,0 +1,91 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_train_flutter/src/feature/route/model/route_legs.dart';
import 'package:latlong2/latlong.dart';
/// Where a waypoint pulled out of the route's line goes (ADR 0030, D59):
/// between the two waypoints of the stretch it was grabbed on.
void main() {
const start = LatLng(47.55, 9.68);
const middle = LatLng(47.53, 9.71);
const end = LatLng(47.50, 9.74);
/// The way planned through start, middle and end: points between each.
const line = [
start,
LatLng(47.545, 9.69),
LatLng(47.54, 9.70),
middle,
LatLng(47.52, 9.72),
LatLng(47.51, 9.73),
end,
];
test(
'a point grabbed on the first stretch goes after the first waypoint',
() {
expect(
insertionIndex(
const [start, middle, end],
line,
const LatLng(47.54, 9.70),
),
1,
);
},
);
test('a point grabbed on the last stretch goes before the last waypoint', () {
expect(
insertionIndex(
const [start, middle, end],
line,
const LatLng(47.515, 9.725),
),
2,
);
});
test('a point grabbed beside the line goes on the stretch nearest it', () {
expect(
insertionIndex(
const [start, middle, end],
line,
const LatLng(47.50, 9.70),
),
2,
);
});
test('a route of two waypoints takes it between them, wherever grabbed', () {
expect(insertionIndex(const [start, end], line, start), 1);
expect(insertionIndex(const [start, end], line, end), 1);
});
test('a route that comes back past a waypoint keeps its stretches in '
'order', () {
// Out to the turn and back the same way: the way back passes the
// first stretch's points again.
const turn = LatLng(47.53, 9.71);
const back = [start, LatLng(47.54, 9.70), turn, LatLng(47.54, 9.70), start];
expect(
insertionIndex(
const [start, turn, start],
back,
const LatLng(47.5401, 9.7001),
),
1,
);
});
test('without a way planned, the straight lines between the waypoints are '
'the line', () {
expect(
insertionIndex(
const [start, middle, end],
const [start, middle, end],
const LatLng(47.52, 9.725),
),
2,
);
});
}