mirror of
https://github.com/kuhyx/diet-guard.git
synced 2026-11-10 19:27:14 +01:00
- FoodEntry.slot -> slotMinute: read via entrySlotMinute, written via slotFields (whole-hour stays byte-identical, else slot_min), kept by copyWithDeleted and the edit screen, so the phone never republishes a stripped copy of a PC entry. Out-of-range peer values echo, never throw. - Satisfaction is nearest-slot snapping (satisfiedSlots) everywhere: loggedSlotsToday, due check, kuchnia occupancy, future-day logged set (that day's schedule), slot selector. Schedule edits no longer un-log. - Future pre-log builds DateTime from slot ~/ 60, slot % 60. - Schedule history + sync go through scheduleToWire/scheduleFromWire. - Notifications: ids are slot minutes; syncToSlots cancels whatever the platform reports active (getActiveNotifications, reminder channel) that is not due, covering legacy hour ids; full 0..1439 sweep only if the lookup throws. - Settings: 15-minute dropdowns + "Custom..." (24h showTimePicker), off-grid values always selectable, counts capped by grid capacity; editor moved to widgets/meal_schedule_editor.dart + meal_time_dropdown.dart. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015npsYVB2PdtWkG7MPAi4tn
58 lines
1.8 KiB
Dart
58 lines
1.8 KiB
Dart
/// Shared fixtures for the "Fill all with catering" tests.
|
|
library;
|
|
|
|
import 'package:diet_guard_app/models/kuchnia_dish.dart';
|
|
import 'package:diet_guard_app/services/document_store.dart';
|
|
import 'package:diet_guard_app/services/kuchnia_spread.dart';
|
|
import 'package:diet_guard_app/services/log_storage_service.dart';
|
|
|
|
/// In-memory store, so these tests need no plugin channel or temp dir.
|
|
class MemoryStore implements DocumentStore {
|
|
/// Stored documents by name.
|
|
final Map<String, String> documents = {};
|
|
|
|
@override
|
|
Future<String?> read(String name) async => documents[name];
|
|
|
|
@override
|
|
Future<void> write(String name, String contents) async {
|
|
documents[name] = contents;
|
|
}
|
|
}
|
|
|
|
/// The default four-slot day.
|
|
const defaultSlots = [480, 720, 960, 1200];
|
|
|
|
/// A dish with the given [priority]; macros are distinct per priority.
|
|
KuchniaDish dish(String name, int priority, {double grams = 300}) =>
|
|
KuchniaDish(
|
|
name: name,
|
|
kcal: 100.0 * priority,
|
|
proteinG: 10.0 * priority,
|
|
carbsG: 20.5,
|
|
fatG: 5,
|
|
grams: grams,
|
|
priority: priority,
|
|
slotLabel: 'Obiad',
|
|
);
|
|
|
|
/// [count] dishes named `D1..Dn` in priority order.
|
|
List<KuchniaDish> dishes(int count) => [
|
|
for (var i = 1; i <= count; i++) dish('D$i', i),
|
|
];
|
|
|
|
/// Pairs [dish] with [slot] directly, bypassing the spread.
|
|
SlottedDish at(KuchniaDish dish, int slot) =>
|
|
SlottedDish(dish: dish, slot: slot);
|
|
|
|
/// Points the singleton at a fresh in-memory log and returns it.
|
|
LogStorageService freshStorage() {
|
|
LogStorageService.resetForTesting(store: MemoryStore());
|
|
return LogStorageService.instance;
|
|
}
|
|
|
|
/// `desc@slot` for every live entry logged today, in write order.
|
|
Future<List<String>> loggedToday(LogStorageService storage) async => [
|
|
for (final e in await storage.todayEntries()) '${e.desc}@${e.slotMinute}',
|
|
];
|