feat(train): weights in pounds too, the person's unit or their region's (ADR 0030, D64)

Every weight is still kept in kilograms. It is shown and entered in the
person's unit, chosen in Your body (Weight in: kg | lb, the profile's
new weightUnit), else the region's: pounds in the US, Liberia and
Myanmar. The entry takes 44 to 880 lb, the same 20 to 400 kg. A weight
left untouched in Your body is saved exactly as it was, not rounded
through pounds. The other figures stay metric.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-04 00:15:55 +01:00
commit 396e010949
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -107,6 +107,13 @@ void main() {
/// Starts Train on a new install ([usedBefore] false), where nobody is
/// signed in, or on one that chose its instance before, signed in unless
/// [signedOut].
/// Puts the test in a region weighing in kilograms (D64): the tests' own,
/// en_US, weighs in pounds.
void inKilograms(WidgetTester tester) {
tester.platformDispatcher.localesTestValue = const [Locale('en', 'GB')];
addTearDown(tester.platformDispatcher.clearLocalesTestValue);
}
Future<void> start(
WidgetTester tester, {
bool usedBefore = false,
@ -1114,9 +1121,64 @@ void main() {
await tester.pumpAndSettle();
}
testWidgets("Your body shows the weight in the region's unit until one is "
'picked, and one left alone stays as it was (D64)', (tester) async {
await tester.runAsync(
() => profile.save(const ProfileContent(weightKg: 64.5)),
);
await openBody(tester);
final weight = find.widgetWithText(TextFormField, 'Weight');
final units = find.byType(SegmentedButton<WeightUnit>);
final form = find
.descendant(
of: find.byType(ProfileForm),
matching: find.byType(Scrollable),
)
.first;
Future<void> save() async {
await tester.scrollUntilVisible(
find.text('Save'),
300,
scrollable: form,
);
await tester.tap(find.text('Save'));
await tester.runAsync(pumpEventQueue);
await tester.pumpAndSettle();
}
// en_US weighs in pounds; 64.5 kg is 142.2 lb, rounded.
expect(
find.descendant(of: weight, matching: find.text('142.2')),
findsOneWidget,
);
await save();
expect(
await tester.runAsync(profile.read),
const ProfileContent(weightKg: 64.5),
reason: 'neither rounded through pounds nor a unit picked',
);
await tester.tap(find.text('Your body'));
await tester.pumpAndSettle();
await tester.tap(
find.descendant(of: units, matching: find.text('kg')),
);
await tester.pump();
expect(
find.descendant(of: weight, matching: find.text('64.5')),
findsOneWidget,
);
await save();
expect(
await tester.runAsync(profile.read),
const ProfileContent(weightKg: 64.5, weightUnit: WeightUnit.kilograms),
);
});
testWidgets('each figure is optional; those given are kept', (
tester,
) async {
inKilograms(tester);
await openBody(tester);
await tester.enterText(
@ -1194,6 +1256,7 @@ void main() {
testWidgets("Profile's card shows the figures given, opens Your body, and "
'follows a change (D60)', (tester) async {
inKilograms(tester);
await tester.runAsync(
() => profile.save(
const ProfileContent(
@ -1234,6 +1297,7 @@ void main() {
testWidgets('a weight entered on Progress shows on its card and in Your '
'body, and goes again from All (D64)', (tester) async {
inKilograms(tester);
await start(tester, usedBefore: true, profile: profile);
await openProgress(tester);
await tester.runAsync(pumpEventQueue);
@ -1283,6 +1347,43 @@ void main() {
expect(find.text('71.4 kg'), findsNothing);
});
testWidgets('a person who weighs in pounds sees and enters pounds, and '
'kilograms are kept (D64)', (tester) async {
await tester.runAsync(
() => profile.save(
const ProfileContent(weightKg: 70, weightUnit: WeightUnit.pounds),
),
);
await start(tester, usedBefore: true, profile: profile);
await openProgress(tester);
await tester.runAsync(pumpEventQueue);
await tester.pump();
final card = find.byType(WeightCard);
await tester.tap(
find.descendant(of: card, matching: find.byTooltip('Add weight')),
);
await tester.pumpAndSettle();
await tester.enterText(find.byType(TextField), '30');
await tester.tap(find.text('Save'));
await tester.pumpAndSettle();
expect(find.text('A weight between 44 and 880 lb'), findsOneWidget);
await tester.enterText(find.byType(TextField), '165');
await tester.tap(find.text('Save'));
await tester.runAsync(pumpEventQueue);
await tester.pumpAndSettle();
await tester.runAsync(pumpEventQueue);
await tester.pumpAndSettle();
expect(
find.descendant(of: card, matching: find.text('165 lb')),
findsOneWidget,
);
final saved = await tester.runAsync(profile.read);
expect(saved?.weightKg, closeTo(74.84, 0.01));
expect(saved?.weightUnit, WeightUnit.pounds);
});
testWidgets("without figures, Profile's card says what they're for", (
tester,
) async {
@ -1447,6 +1548,7 @@ void main() {
testWidgets('what the profile lacks is asked alone and needed; then '
'kept, and the band set up', (tester) async {
inKilograms(tester);
await tester.runAsync(
() => profile.save(
ProfileContent(