Files
doormile_milderapp/test/accepted_count_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

107 lines
3.5 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:miler/data/service_profile.dart';
import 'package:miler/views/Dashboard/home/trip.dart';
/// ─────────────────────────────────────────────────────────────────────────
/// THE FLOATING COUNT IS DERIVED, NOT KEPT
///
/// It read the length of a persisted "accepted bookings" list. That store is
/// written on accept and cleaned on completion, so a stop that left the day any
/// other way — the hub pulling it, a reject racing a refetch, yesterday's run —
/// stayed in it and the pill counted work the rider did not have. Two accepted
/// stops could read as twelve.
///
/// The trip already knows. This pins the derivation the pill now uses, against
/// the same accepted/rejected sets every other surface on Home reads.
/// ─────────────────────────────────────────────────────────────────────────
int waiting(
Trip trip, {
required Set<String> accepted,
Set<String> rejected = const {},
}) => trip
.states(acceptedIds: accepted, rejectedIds: rejected)
.where((s) => s == StopState.accepted || s == StopState.collected)
.length;
void main() {
tearDown(() => ServiceProfile.setActive(ServiceProfile.parcel));
Map<String, dynamic> stop(String id, {String status = 'new'}) => {
'orderid': id,
'pickupcustomer': 'Stop $id',
'pickupaddress': '12 Main Rd, Coimbatore',
'orderstatus': status,
'Quantity': 1,
};
Trip four() => Trip.fromStops(
id: 't',
stops: [stop('A'), stop('B'), stop('C'), stop('D')],
);
test('nothing accepted is zero, not the size of the day', () {
expect(waiting(four(), accepted: const {}), 0);
});
test('two accepted reads exactly two', () {
expect(waiting(four(), accepted: const {'A', 'B'}), 2);
});
test('five accepted reads exactly five', () {
final trip = Trip.fromStops(
id: 't',
stops: [for (var i = 0; i < 6; i++) stop('S$i')],
);
expect(waiting(trip, accepted: {for (var i = 0; i < 5; i++) 'S$i'}), 5);
});
test('rejecting one drops it in the same frame', () {
final trip = four();
expect(waiting(trip, accepted: const {'A', 'B', 'C'}), 3);
// The rider declines C. Same trip, same accepted set — the rejected set is
// what changed, and a rejection outranks a stale accept.
expect(
waiting(trip, accepted: const {'A', 'B', 'C'}, rejected: const {'C'}),
2,
);
});
test('a finished stop stops counting', () {
final trip = Trip.fromStops(
id: 't',
stops: [
stop('A', status: 'picked'),
stop('B'),
],
);
expect(
waiting(trip, accepted: const {'A', 'B'}),
1,
reason: 'A is done; only B is still waiting on the work tab',
);
});
test('the stop he is standing at is not "waiting for him"', () {
final trip = Trip.fromStops(
id: 't',
stops: [
stop('A', status: 'active'),
stop('B'),
],
);
expect(waiting(trip, accepted: const {'A', 'B'}), 1);
});
test('a cancelled stop stops counting', () {
final trip = Trip.fromStops(
id: 't',
stops: [
stop('A', status: 'cancelled'),
stop('B'),
],
);
expect(waiting(trip, accepted: const {'A', 'B'}), 1);
});
}