import 'package:flutter_test/flutter_test.dart'; import 'package:life_helper/domain/models/habit.dart'; import 'package:life_helper/domain/models/tracker_entry.dart'; import 'package:life_helper/domain/streak/weekly_minimum_ratio.dart'; HabitDoseVariantModel _v(String id, {bool isMin = false}) => HabitDoseVariantModel( variantId: id, habitId: 'hb', label: id, doseText: '1x', isMinimum: isMin, ); TrackerEntryModel _done(String date, {String? vId}) => TrackerEntryModel( id: 'te_$date', habitId: 'hb', date: date, value: TrackerValue.done, variantId: vId, ); void main() { final variantsById = { 'min': _v('min', isMin: true), 'full': _v('full'), }; test('no done entries → ratio 0.0', () { final r = computeWeeklyMinimumRatio( entries: const [], variantsById: variantsById, asOf: DateTime(2026, 6, 11), ); expect(r.totalDone, 0); expect(r.ratio, 0.0); }); test('3 of 4 used minimum → 0.75', () { final r = computeWeeklyMinimumRatio( entries: [ _done('2026-06-08', vId: 'min'), _done('2026-06-09', vId: 'min'), _done('2026-06-10', vId: 'full'), _done('2026-06-11', vId: 'min'), ], variantsById: variantsById, asOf: DateTime(2026, 6, 11), ); expect(r.totalDone, 4); expect(r.minimumUsed, 3); expect(r.ratio, closeTo(0.75, 1e-9)); }); test('out-of-window entries are excluded', () { final r = computeWeeklyMinimumRatio( entries: [ _done('2026-06-01', vId: 'min'), // 10 days before asOf _done('2026-06-11', vId: 'min'), ], variantsById: variantsById, asOf: DateTime(2026, 6, 11), ); expect(r.totalDone, 1); expect(r.minimumUsed, 1); }); test('done with null variantId counts as totalDone but not minimumUsed', () { final r = computeWeeklyMinimumRatio( entries: [ _done('2026-06-10'), _done('2026-06-11', vId: 'min'), ], variantsById: variantsById, asOf: DateTime(2026, 6, 11), ); expect(r.totalDone, 2); expect(r.minimumUsed, 1); expect(r.ratio, 0.5); }); }