#include "TestHarness.h" #include "src/reminder/ReminderParser.h" #include "src/reminder/ReminderTypes.h" #include #include #include #include namespace { QDateTime fixedNow() { return QDateTime(QDate(2026, 7, 17), QTime(14, 0)); } } QA_TEST(ReminderParser, ParsesRelativeMinutes) { const ReminderCommand command = ReminderParser().parse(QStringLiteral("10分钟后提醒我喝水"), fixedNow()); QA_EXPECT_EQ(command.type, ReminderCommandType::Create); QA_EXPECT_EQ(command.remindAt, fixedNow().addSecs(10 * 60)); QA_EXPECT_EQ(command.title, QStringLiteral("喝水")); } QA_TEST(ReminderParser, ParsesHalfHours) { const ReminderParser parser; QA_EXPECT_EQ( parser.parse(QStringLiteral("半小时后提醒我休息"), fixedNow()).remindAt, fixedNow().addSecs(30 * 60)); QA_EXPECT_EQ( parser.parse(QStringLiteral("一个半小时后提醒我喝水"), fixedNow()).remindAt, fixedNow().addSecs(90 * 60)); } QA_TEST(ReminderParser, ParsesTomorrowClockTime) { const ReminderCommand command = ReminderParser().parse(QStringLiteral("明天9点提醒我开会"), fixedNow()); QA_EXPECT_EQ(command.type, ReminderCommandType::Create); QA_EXPECT_EQ(command.remindAt, QDateTime(QDate(2026, 7, 18), QTime(9, 0))); } QA_TEST(ReminderParser, ParsesSupportedRecurrence) { const ReminderParser parser; const ReminderCommand daily = parser.parse(QStringLiteral("每天9点提醒我打卡"), fixedNow()); const ReminderCommand weekly = parser.parse(QStringLiteral("每周一上午10点提醒我周会"), fixedNow()); const ReminderCommand monthly = parser.parse(QStringLiteral("每月31号9点提醒我交报告"), fixedNow()); QA_EXPECT_EQ(daily.recurrence.type, ReminderRecurrenceType::Daily); QA_EXPECT_EQ(daily.remindAt, QDateTime(QDate(2026, 7, 18), QTime(9, 0))); QA_EXPECT_EQ(weekly.recurrence.type, ReminderRecurrenceType::Weekly); QA_EXPECT_EQ(weekly.recurrence.weekday, 1); QA_EXPECT_EQ(monthly.recurrence.type, ReminderRecurrenceType::Monthly); QA_EXPECT_EQ(monthly.recurrence.monthDay, 31); QA_EXPECT_EQ(monthly.remindAt, QDateTime(QDate(2026, 7, 31), QTime(9, 0))); } QA_TEST(ReminderParser, RejectsUnsupportedRecurrence) { const ReminderParser parser; const QStringList requests = { QStringLiteral("工作日9点提醒我打卡"), QStringLiteral("每两天提醒我喝水"), QStringLiteral("农历初一提醒我"), QStringLiteral("每月最后一天9点提醒我结算"), }; for (const QString &request : requests) { const ReminderCommand command = parser.parse(request, fixedNow()); QA_EXPECT_EQ(command.type, ReminderCommandType::Invalid); QA_EXPECT(!command.errorMessage.isEmpty()); } } QA_TEST(ReminderParser, ParsesListAndCancelCommands) { const ReminderParser parser; QA_EXPECT_EQ(parser.parse(QStringLiteral("提醒列表"), fixedNow()).type, ReminderCommandType::List); const ReminderCommand cancel = parser.parse(QStringLiteral("取消喝水提醒"), fixedNow()); QA_EXPECT_EQ(cancel.type, ReminderCommandType::Cancel); QA_EXPECT_EQ(cancel.cancelQuery, QStringLiteral("喝水")); } QA_TEST(ReminderTypes, ConvertsAndSortsValues) { QA_EXPECT_EQ(reminderStatusFromString(QStringLiteral("TRIGGERED")), ReminderStatus::Triggered); QA_EXPECT_EQ(reminderRecurrenceTypeFromString(QStringLiteral("weekly")), ReminderRecurrenceType::Weekly); QA_EXPECT_EQ(reminderRecurrenceTypeToString(ReminderRecurrenceType::Monthly), QStringLiteral("monthly")); ReminderItem later; later.id = QStringLiteral("later"); later.remindAt = fixedNow().addSecs(60); ReminderItem earlier; earlier.id = QStringLiteral("earlier"); earlier.remindAt = fixedNow(); const QVector sorted = sortedReminders({later, earlier}); QA_EXPECT_EQ(sorted.first().id, QStringLiteral("earlier")); QA_EXPECT_EQ(sorted.last().id, QStringLiteral("later")); }