frindlymap/test/events_test.dart

95 lines
3.9 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:friendly_map/modules/events/events.dart';
void main() {
final today = DateTime(2026, 10, 26);
group('일정 계산', () {
test('올해 지났으면 내년, 오늘이면 오늘', () {
const b = FamilyEvent(personId: 'a', kind: EventKind.birthday, month: 3, day: 5, year: 1960);
expect(b.nextFrom(today), DateTime(2027, 3, 5));
const t = FamilyEvent(personId: 'a', kind: EventKind.birthday, month: 10, day: 26);
expect(t.nextFrom(today), DateTime(2026, 10, 26));
});
test('2월 29일은 평년엔 28일', () {
const e = FamilyEvent(personId: 'a', kind: EventKind.birthday, month: 2, day: 29);
expect(e.occurrenceIn(2027), DateTime(2027, 2, 28));
expect(e.occurrenceIn(2028), DateTime(2028, 2, 29));
});
test('다가오는 일정은 가까운 순, 범위 밖은 제외, 나이·주기 계산', () {
final list = upcoming(const [
FamilyEvent(personId: 'far', kind: EventKind.birthday, month: 1, day: 1),
FamilyEvent(personId: 'b', kind: EventKind.memorial, month: 11, day: 10, year: 2016),
FamilyEvent(personId: 'a', kind: EventKind.birthday, month: 10, day: 28, year: 1990),
], today, withinDays: 30);
expect(list.map((e) => e.event.personId).toList(), ['a', 'b']);
expect(list[0].daysLeft, 2);
expect(list[0].years, 36);
expect(list[1].years, 10);
expect(dayWord(0), '오늘');
expect(dayWord(1), '내일');
expect(dayWord(5), '5일 후');
});
test('라벨', () {
const m = FamilyEvent(personId: 'a', kind: EventKind.memorial, month: 1, day: 1);
expect(m.label('할아버지'), '할아버지 기일');
});
});
group('알림 일정', () {
test('설정 글자 해석: 1일 전, 2일 전, 중복·잘못된 칸 정리', () {
expect(parseLeadDays('1일 전, 2일 전'), [2, 1]);
expect(parseLeadDays('7, 1, 1, x, 0'), [7, 1, 0]);
expect(parseLeadDays(null), isEmpty);
expect(leadDaysText([7, 1]), '7, 1');
});
test('이미 지난 알림은 빼고 시각순', () {
const e = FamilyEvent(personId: 'a', kind: EventKind.birthday, month: 10, day: 28);
final now = DateTime(2026, 10, 26, 10); // 9시는 지남
final plans = planReminders([e], now, [2, 1, 0], (_) => '엄마');
// 2일 전(10/26 09:00)은 지남 → 1일 전, 당일만
expect(plans.map((p) => p.leadDays).toList(), [1, 0]);
expect(plans.first.fireAt, DateTime(2026, 10, 27, 9));
expect(plans.first.text, '내일 엄마 생일입니다');
expect(plans.last.text, '오늘 엄마 생일입니다');
});
test('너무 먼 일정은 제외', () {
const e = FamilyEvent(personId: 'a', kind: EventKind.birthday, month: 6, day: 1);
expect(planReminders([e], today, [1], (_) => 'x'), isEmpty);
});
});
group('통화 요약', () {
test('기록 없음', () {
expect(summarizeCalls(const []).total, 0);
});
test('횟수·부재중·총 시간·마지막 통화·자주 받는 시간대', () {
final s = summarizeCalls([
CallRecord(DateTime(2026, 10, 1, 19, 5), 600, CallDirection.outgoing),
CallRecord(DateTime(2026, 10, 8, 19, 40), 300, CallDirection.incoming),
CallRecord(DateTime(2026, 10, 15, 8, 10), 60, CallDirection.outgoing),
CallRecord(DateTime(2026, 10, 20, 14, 0), 0, CallDirection.missed),
]);
expect(s.total, 4);
expect(s.answered, 3);
expect(s.missed, 1);
expect(s.totalSeconds, 960);
expect(s.averageSeconds, 320);
expect(s.lastAt, DateTime(2026, 10, 20, 14, 0));
expect(s.lastDirection, CallDirection.missed);
expect(s.windows.first.fromHour, 19);
expect(s.windows.first.label, '오후 7시 ~ 오후 8시');
expect(s.windows.length, 2);
expect(durationText(45), '45초');
expect(durationText(600), '10분');
expect(durationText(4000), '1시간 6분');
});
});
}