diff --git a/Package.swift b/Package.swift index 0027bec..92173c6 100644 --- a/Package.swift +++ b/Package.swift @@ -38,6 +38,16 @@ let package = Package( dependencies: [ .target(name: "PluginBinary") ] + ), + .testTarget( + name: "DoNilDisturbPluginTests", + dependencies: [ + .target(name: "PluginBinary"), + .product(name: "iCalendar", package: "iCalendar") + ], + resources: [ + .copy("Resources"), + ] ) ] ) diff --git a/PluginBinary/PluginBinary.swift b/PluginBinary/PluginBinary.swift index ec28459..594d690 100644 --- a/PluginBinary/PluginBinary.swift +++ b/PluginBinary/PluginBinary.swift @@ -25,7 +25,7 @@ extension String: Error { } log("Holidays: \(calPath.replacingOccurrences(of: invocation.packagePath + "/", with: ""))") } - let holidayColendars = try invocation.calendarPaths + let holidayCalendars = try invocation.calendarPaths .compactMap({ return Parser.parse(ics: try String(contentsOfFile: $0)).value }) @@ -38,7 +38,7 @@ extension String: Error { } // let date = dateFormatter.date(from:isoDate)! let date = Date() - let content = content(for: date, holidayColendars: holidayColendars) + let content = content(for: date, holidayCalendars: holidayCalendars) try content.write(to: outputURL, atomically: true, encoding: .utf8) log("Written '\(invocation.sourcePath)'") @@ -47,16 +47,22 @@ extension String: Error { } try writeLog(at: URL(fileURLWithPath: invocation.logPath)) } - static func content(for date: Date, holidayColendars: [iCalendar.Calendar]) -> String { + static func content(for date: Date, holidayCalendars: [iCalendar.Calendar], systemCalendar: Foundation.Calendar = .current) -> String { log("Current date: \(date.debugDescription)") - let dateFormatter = DateFormatter() - dateFormatter.dateFormat = "MM-dd-yy" - - if let holidaySummary = holidayColendars + if let holidaySummary = holidayCalendars .mapFirst(where: { calendar in return calendar.events.mapFirst { event in - if dateFormatter.string(from: date) == dateFormatter.string(from: event.startDate) { log("ITS NOW!") + // iCalendar creates dates for all-day things at noon rather than midnight, so we need to compare date components instead of dates + let startDateComponents = systemCalendar.dateComponents([.year, .month, .day], from: event.startDate) + let currentDateComponents = systemCalendar.dateComponents([.year, .month, .day], from: date) + log("Start components: \(startDateComponents)") + log("Current components: \(currentDateComponents)") + + if startDateComponents.year == currentDateComponents.year, + startDateComponents.month == currentDateComponents.month, + startDateComponents.day == currentDateComponents.day { + log("ITS NOW!") return "It is \(event.summary ?? "a holiday")" } return nil @@ -66,15 +72,19 @@ extension String: Error { } return content(withReason: holidaySummary) } - if Calendar.current.isDateInWeekend(date) { // Exclude weekend + if systemCalendar.isDateInWeekend(date) { // Exclude weekend return content(withReason: "It's the weekend") - } else if (9.0...18.0 ~= date.time) { // Your 9-6 basically - let formatter = DateFormatter() - formatter.dateStyle = .none - return content(withReason: "It's \(formatter.string(from: date))") + } else if (9.0...18.0 ~= date.time) { + // Time is in the 9am-6pm range + return "// All is good, do not disturb is off." } - - return "// All is good, do not disturb is off." + + let formatter = DateFormatter() + formatter.dateStyle = .none + formatter.timeStyle = .short + formatter.locale = systemCalendar.locale + + return content(withReason: "It's \(formatter.string(from: date))") } private static func content(withReason reason: String) -> String { diff --git a/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift b/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift new file mode 100644 index 0000000..31941cf --- /dev/null +++ b/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift @@ -0,0 +1,63 @@ +import XCTest +import Foundation +import iCalendar + +@testable import PluginBinary + +final class DoNotDisturbPluginTests: XCTestCase { + + func testHolidayLoad() throws { + let date = Foundation.Calendar.current.date(from: DateComponents(year: 2022, month: 8, day: 30, hour: 13))! + let calendarFileURL = try XCTUnwrap(Bundle.module.url(forResource: "TestCal", withExtension: "ics", subdirectory: "Resources")) + let icalContents = try String(contentsOf: calendarFileURL) + let parseResult = Parser.parse(ics: icalContents) + switch parseResult { + case .success(let calendar): + let content = PluginBinary.content(for: date, holidayCalendars: [calendar]) + XCTAssertEqual(content, +""" +#error("Do not disturb is ON") +#warning("It is The Feast of Maximum Occupancy") +""") + case .failure(let error): + XCTFail(error.localizedDescription) + } + } + + func testWeekendError() throws { + let sunday = Calendar.current.date(from: DateComponents(year: 2022, month: 08, day: 28))! + + let content = PluginBinary.content(for: sunday, holidayCalendars: []) + XCTAssertEqual(content, +""" +#error("Do not disturb is ON") +#warning("It's the weekend") +""") + } + + func test2amError() { + var calendar = Foundation.Calendar.current + + // Prevents errors when the calendar is in a different locale + calendar.locale = Locale(identifier: "en-US") + + let monday2am = calendar.date(from: DateComponents(year: 2022, month: 08, day: 29, hour: 2))! + + let content = PluginBinary.content(for: monday2am, + holidayCalendars: [], + systemCalendar: calendar) + XCTAssertEqual(content, +""" +#error("Do not disturb is ON") +#warning("It's 2:00 AM") +""") + } + + func testWorkTime() { + let monday2pm = Calendar.current.date(from: DateComponents(year: 2022, month: 08, day: 29, hour: 14))! + let content = PluginBinary.content(for: monday2pm, holidayCalendars: []) + XCTAssertEqual(content, "// All is good, do not disturb is off.") + } + + +} diff --git a/Tests/DoNilDisturbPluginTests/Resources/TestCal.ics b/Tests/DoNilDisturbPluginTests/Resources/TestCal.ics new file mode 100644 index 0000000..091def0 --- /dev/null +++ b/Tests/DoNilDisturbPluginTests/Resources/TestCal.ics @@ -0,0 +1,21 @@ +BEGIN:VCALENDAR +METHOD:PUBLISH +VERSION:2.0 +X-WR-CALNAME:TestCal +PRODID:-//Apple Inc.//macOS 12.5.1//EN +X-APPLE-CALENDAR-COLOR:#0E61B9 +X-WR-TIMEZONE:America/Denver +CALSCALE:GREGORIAN +BEGIN:VEVENT +CREATED:20220829T020826Z +UID:413F797E-DA05-4920-AF63-D6A2E2D5CDC8 +DTSTART;VALUE=DATE:20220830 +DTEND;VALUE=DATE:20220831 +TRANSP:TRANSPARENT +X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC +SUMMARY:The Feast of Maximum Occupancy +LAST-MODIFIED:20220829T020840Z +DTSTAMP:20220829T020840Z +SEQUENCE:1 +END:VEVENT +END:VCALENDAR diff --git a/Tests/DoNotDisturbPluginTests/DoNotDisturbPluginTests.swift b/Tests/DoNotDisturbPluginTests/DoNotDisturbPluginTests.swift deleted file mode 100644 index cead898..0000000 --- a/Tests/DoNotDisturbPluginTests/DoNotDisturbPluginTests.swift +++ /dev/null @@ -1,7 +0,0 @@ -import XCTest -@testable import DoNotDisturbPlugin - -final class DoNotDisturbPluginTests: XCTestCase { - func testExample() throws { - } -}