parseRecurrence required a space ("every day"), so "everyday" (one word) was
missed. Now \bevery\s*day\b matches both, plus "each day". Added Every Weekday
detection ("every weekday", "weekdays") ahead of the broader weekly/daily
patterns. Sub-day cadence ("every hour"/"hourly") is intentionally NOT matched —
the occurrence engine is day-granular, so it stays a one-off rather than being
mislabeled. 6 parser tests added.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
52 lines
1.8 KiB
Swift
52 lines
1.8 KiB
Swift
import XCTest
|
|
@testable import KisaniCal
|
|
|
|
/// Natural-language recurrence detection in the quick-add parser.
|
|
final class NLRecurrenceParseTests: XCTestCase {
|
|
|
|
private func label(_ s: String) -> String? {
|
|
NLTaskParser.parse(s).recurrenceLabel
|
|
}
|
|
|
|
func testDailyVariants() {
|
|
XCTAssertEqual(label("remind me to pray everyday"), "Daily") // the reported case
|
|
XCTAssertEqual(label("remind me to pray every day"), "Daily")
|
|
XCTAssertEqual(label("stretch daily"), "Daily")
|
|
XCTAssertEqual(label("read each day"), "Daily")
|
|
}
|
|
|
|
func testWeekdayVsWeekly() {
|
|
XCTAssertEqual(label("standup every weekday"), "Every Weekday")
|
|
XCTAssertEqual(label("standup weekdays"), "Every Weekday")
|
|
XCTAssertEqual(label("groceries every week"), "Weekly")
|
|
XCTAssertEqual(label("groceries weekly"), "Weekly")
|
|
}
|
|
|
|
func testMonthlyYearly() {
|
|
XCTAssertEqual(label("pay rent every month"), "Monthly")
|
|
XCTAssertEqual(label("pay rent monthly"), "Monthly")
|
|
XCTAssertEqual(label("renew every year"), "Yearly")
|
|
XCTAssertEqual(label("renew annually"), "Yearly")
|
|
XCTAssertEqual(label("file taxes yearly"), "Yearly")
|
|
}
|
|
|
|
func testBirthdayIsYearly() {
|
|
let p = NLTaskParser.parse("Jay's birthday")
|
|
XCTAssertTrue(p.isBirthday)
|
|
XCTAssertTrue(p.isRecurring)
|
|
XCTAssertEqual(p.recurrenceLabel, "Yearly")
|
|
}
|
|
|
|
func testNonRecurringStaysNil() {
|
|
XCTAssertNil(label("buy milk"))
|
|
XCTAssertNil(label("call mom tomorrow"))
|
|
}
|
|
|
|
/// Sub-day cadence isn't supported by the (day-granular) occurrence engine, so it
|
|
/// must NOT be mislabeled as Daily/etc. — it stays a one-off.
|
|
func testHourlyIsNotMisclassified() {
|
|
XCTAssertNil(label("drink water every hour"))
|
|
XCTAssertNil(label("check oven hourly"))
|
|
}
|
|
}
|