diet-guard/app/test/widgets/day_status_calendar_test.dart
Krzysztof kuhy Rudnicki c0ed6154ac Split the remaining seven Dart test files
Eleventh batch of the 250-line sweep (over-cap count 12 -> 5). Every test file
in the repo, Python and Dart, is now under cap; the five left are all in
app/lib/.

  wrapper_server_test.dart        349 -> 145  (+ proxy, account siblings)
  app_settings_service_test.dart  321 -> 162  (+ sync sibling)
  average_service_test.dart       299 -> 158  (+ periods sibling)
  settings_screen_test.dart       274 -> 189  (+ battery sibling)
  day_status_service_test.dart    270 -> 161  (+ streaks sibling)
  edit_entry_screen_test.dart     269 -> 159  (+ foodbank sibling)
  day_status_calendar_test.dart   256 -> 237  (+ _test_support sibling)

day_status_calendar_test is a single group whose tests close over group-local
state, so it could not be split by block. Its ~25 lines of file-level fixtures
moved to `day_status_calendar_test_support.dart` instead, which required the
same publicisation as the sync support file (`_theme` -> `appTheme`, `_wrap` ->
`wrapInApp`, `_colorOfDay` -> `colorOfDay`) with doc comments.

Block counts were compared against HEAD per family rather than trusting the
suite total, since the duplication bug in the previous batch passed green at an
inflated count. All seven families match exactly (29/26/34/11/34/8/14).

Verified: flutter test 555 (unchanged), flutter analyze clean, pre-commit
clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RA9ynjqXPnexRQnR5oAuCC
2026-08-15 20:53:55 +02:00

238 lines
6.5 KiB
Dart

import 'package:diet_guard_app/models/day_status.dart';
import 'package:diet_guard_app/widgets/day_status_calendar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'day_status_calendar_test_support.dart';
void main() {
group('DayStatusCalendar', () {
final june2026 = DateTime(2026, 6);
final juneToday = DateTime(2026, 6, 20);
testWidgets('shows month and year in header', (tester) async {
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {},
month: june2026,
today: juneToday,
onPrevMonth: () {},
onNextMonth: () {},
),
),
);
expect(find.text('June 2026'), findsOneWidget);
});
testWidgets('shows day-of-week headers', (tester) async {
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {},
month: june2026,
today: juneToday,
onPrevMonth: () {},
onNextMonth: () {},
),
),
);
expect(find.text('Mo'), findsOneWidget);
expect(find.text('Su'), findsOneWidget);
});
testWidgets('calls onPrevMonth when left arrow tapped', (tester) async {
var called = false;
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {},
month: june2026,
today: juneToday,
onPrevMonth: () => called = true,
onNextMonth: () {},
),
),
);
await tester.tap(find.byIcon(Icons.chevron_left));
expect(called, isTrue);
});
testWidgets('calls onNextMonth when right arrow tapped', (tester) async {
var called = false;
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {},
month: june2026,
today: juneToday,
onPrevMonth: () {},
onNextMonth: () => called = true,
),
),
);
await tester.tap(find.byIcon(Icons.chevron_right));
expect(called, isTrue);
});
testWidgets('colors a green day', (tester) async {
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {'2026-06-15': DayStatus.green},
month: june2026,
today: juneToday,
onPrevMonth: () {},
onNextMonth: () {},
),
),
);
expect(colorOfDay(tester, '15'), statusColors.success);
});
testWidgets('colors a yellow day', (tester) async {
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {'2026-06-15': DayStatus.yellow},
month: june2026,
today: juneToday,
onPrevMonth: () {},
onNextMonth: () {},
),
),
);
expect(colorOfDay(tester, '15'), statusColors.warning);
});
testWidgets('colors a red day', (tester) async {
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {'2026-06-15': DayStatus.red},
month: june2026,
today: juneToday,
onPrevMonth: () {},
onNextMonth: () {},
),
),
);
expect(colorOfDay(tester, '15'), appTheme.colorScheme.error);
});
testWidgets(
'a past day absent from statusByDate renders black (not logged)',
(tester) async {
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {},
month: june2026,
today: juneToday,
onPrevMonth: () {},
onNextMonth: () {},
),
),
);
expect(colorOfDay(tester, '15'), appTheme.colorScheme.surface);
},
);
testWidgets(
'a future day renders neutrally, never as a false not-logged cell',
(tester) async {
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {},
month: june2026,
today: DateTime(2026, 6, 10),
onPrevMonth: () {},
onNextMonth: () {},
),
),
);
// Day 25 is after the reference "today" of June 10.
expect(
colorOfDay(tester, '25'),
appTheme.colorScheme.surfaceContainerHigh,
);
},
);
testWidgets('today itself is classified, not treated as future', (
tester,
) async {
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {'2026-06-20': DayStatus.red},
month: june2026,
today: juneToday,
onPrevMonth: () {},
onNextMonth: () {},
),
),
);
expect(colorOfDay(tester, '20'), appTheme.colorScheme.error);
});
testWidgets('renders a month starting on Sunday correctly', (
tester,
) async {
final sep2026 = DateTime(2026, 9);
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {},
month: sep2026,
today: DateTime(2026, 9),
onPrevMonth: () {},
onNextMonth: () {},
),
),
);
expect(find.text('September 2026'), findsOneWidget);
});
testWidgets('tapping a day calls onDaySelected with that date', (
tester,
) async {
DateTime? selected;
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {'2026-06-15': DayStatus.green},
month: june2026,
today: juneToday,
onPrevMonth: () {},
onNextMonth: () {},
onDaySelected: (day) => selected = day,
),
),
);
await tester.tap(find.text('15'));
expect(selected, DateTime(2026, 6, 15));
});
testWidgets('no onDaySelected means day cells are not tappable', (
tester,
) async {
await tester.pumpWidget(
wrapInApp(
DayStatusCalendar(
statusByDate: const {},
month: june2026,
today: juneToday,
onPrevMonth: () {},
onNextMonth: () {},
),
),
);
// No GestureDetector wraps the day cells when onDaySelected is null;
// tapping must not throw.
await tester.tap(find.text('15'));
});
});
}