From 23bc3883559f2125d5ed01885420ce4deac30881 Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Sun, 28 Aug 2022 21:48:53 -0600 Subject: [PATCH 1/5] Update the binary to use date component math instead of formatters --- PluginBinary/PluginBinary.swift | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/PluginBinary/PluginBinary.swift b/PluginBinary/PluginBinary.swift index ec28459..4a11648 100644 --- a/PluginBinary/PluginBinary.swift +++ b/PluginBinary/PluginBinary.swift @@ -50,13 +50,16 @@ extension String: Error { } static func content(for date: Date, holidayColendars: [iCalendar.Calendar]) -> String { log("Current date: \(date.debugDescription)") - let dateFormatter = DateFormatter() - dateFormatter.dateFormat = "MM-dd-yy" - if let holidaySummary = holidayColendars .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 = Foundation.Calendar.current.dateComponents([.year, .month, .day], from: event.startDate) + let currentDateComponents = Foundation.Calendar.current.dateComponents([.year, .month, .day], from: date) + 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 From 4780a4d7a1313f73cc497fb17cc5582736521410 Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Sun, 28 Aug 2022 22:06:52 -0600 Subject: [PATCH 2/5] Enable tests and actually test formatting, find and fix flipped 9-6 inclusivity --- Package.swift | 7 +- PluginBinary/PluginBinary.swift | 24 ++++--- .../DoNotDisturbPluginTests.swift | 65 +++++++++++++++++++ Tests/DoNilDisturbPluginTests/TestCal.ics | 21 ++++++ .../DoNotDisturbPluginTests.swift | 7 -- 5 files changed, 106 insertions(+), 18 deletions(-) create mode 100644 Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift create mode 100644 Tests/DoNilDisturbPluginTests/TestCal.ics delete mode 100644 Tests/DoNotDisturbPluginTests/DoNotDisturbPluginTests.swift diff --git a/Package.swift b/Package.swift index 0027bec..67d0585 100644 --- a/Package.swift +++ b/Package.swift @@ -38,6 +38,11 @@ let package = Package( dependencies: [ .target(name: "PluginBinary") ] - ) + ), + .testTarget(name: "DoNilDisturbPluginTests", + dependencies: [ + .target(name: "PluginBinary"), + .product(name: "iCalendar", package: "iCalendar") + ]) ] ) diff --git a/PluginBinary/PluginBinary.swift b/PluginBinary/PluginBinary.swift index 4a11648..8f37edf 100644 --- a/PluginBinary/PluginBinary.swift +++ b/PluginBinary/PluginBinary.swift @@ -47,15 +47,15 @@ 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, holidayColendars: [iCalendar.Calendar], systemCalendar: Foundation.Calendar = .current) -> String { log("Current date: \(date.debugDescription)") if let holidaySummary = holidayColendars .mapFirst(where: { calendar in return calendar.events.mapFirst { event in // iCalendar creates dates for all-day things at noon rather than midnight, so we need to compare date components instead of dates - let startDateComponents = Foundation.Calendar.current.dateComponents([.year, .month, .day], from: event.startDate) - let currentDateComponents = Foundation.Calendar.current.dateComponents([.year, .month, .day], from: date) + let startDateComponents = systemCalendar.dateComponents([.year, .month, .day], from: event.startDate) + let currentDateComponents = systemCalendar.dateComponents([.year, .month, .day], from: date) if startDateComponents.year == currentDateComponents.year, startDateComponents.month == currentDateComponents.month, startDateComponents.day == currentDateComponents.day { @@ -69,15 +69,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..9dc4542 --- /dev/null +++ b/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift @@ -0,0 +1,65 @@ +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 path = #filePath + let parent = (path as NSString).deletingLastPathComponent + let icalPath = parent.appending("/TestCal.ics") + let icalContents = try String(contentsOfFile: icalPath) + let parseResult = Parser.parse(ics: icalContents) + switch parseResult { + case .success(let calendar): + let content = PluginBinary.content(for: date, holidayColendars: [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, holidayColendars: []) + 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, + holidayColendars: [], + 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, holidayColendars: []) + XCTAssertEqual(content, "// All is good, do not disturb is off.") + } + + +} diff --git a/Tests/DoNilDisturbPluginTests/TestCal.ics b/Tests/DoNilDisturbPluginTests/TestCal.ics new file mode 100644 index 0000000..091def0 --- /dev/null +++ b/Tests/DoNilDisturbPluginTests/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 { - } -} From acaaa5d611967ea935509a74305440b4168f6729 Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Sun, 28 Aug 2022 22:08:15 -0600 Subject: [PATCH 3/5] fix typo --- PluginBinary/PluginBinary.swift | 8 ++++---- .../DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/PluginBinary/PluginBinary.swift b/PluginBinary/PluginBinary.swift index 8f37edf..6db36f1 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,10 +47,10 @@ extension String: Error { } try writeLog(at: URL(fileURLWithPath: invocation.logPath)) } - static func content(for date: Date, holidayColendars: [iCalendar.Calendar], systemCalendar: Foundation.Calendar = .current) -> String { + static func content(for date: Date, holidayCalendars: [iCalendar.Calendar], systemCalendar: Foundation.Calendar = .current) -> String { log("Current date: \(date.debugDescription)") - if let holidaySummary = holidayColendars + if let holidaySummary = holidayCalendars .mapFirst(where: { calendar in return calendar.events.mapFirst { event in // iCalendar creates dates for all-day things at noon rather than midnight, so we need to compare date components instead of dates diff --git a/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift b/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift index 9dc4542..b07801e 100644 --- a/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift +++ b/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift @@ -15,7 +15,7 @@ final class DoNotDisturbPluginTests: XCTestCase { let parseResult = Parser.parse(ics: icalContents) switch parseResult { case .success(let calendar): - let content = PluginBinary.content(for: date, holidayColendars: [calendar]) + let content = PluginBinary.content(for: date, holidayCalendars: [calendar]) XCTAssertEqual(content, """ #error("Do not disturb is ON") @@ -29,7 +29,7 @@ final class DoNotDisturbPluginTests: XCTestCase { func testWeekendError() throws { let sunday = Calendar.current.date(from: DateComponents(year: 2022, month: 08, day: 28))! - let content = PluginBinary.content(for: sunday, holidayColendars: []) + let content = PluginBinary.content(for: sunday, holidayCalendars: []) XCTAssertEqual(content, """ #error("Do not disturb is ON") @@ -46,7 +46,7 @@ final class DoNotDisturbPluginTests: XCTestCase { let monday2am = calendar.date(from: DateComponents(year: 2022, month: 08, day: 29, hour: 2))! let content = PluginBinary.content(for: monday2am, - holidayColendars: [], + holidayCalendars: [], systemCalendar: calendar) XCTAssertEqual(content, """ @@ -57,7 +57,7 @@ final class DoNotDisturbPluginTests: XCTestCase { func testWorkTime() { let monday2pm = Calendar.current.date(from: DateComponents(year: 2022, month: 08, day: 29, hour: 14))! - let content = PluginBinary.content(for: monday2pm, holidayColendars: []) + let content = PluginBinary.content(for: monday2pm, holidayCalendars: []) XCTAssertEqual(content, "// All is good, do not disturb is off.") } From 88fcfea8eb900eb6dab104d6580c1a11fcc75bcf Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Sun, 28 Aug 2022 22:18:11 -0600 Subject: [PATCH 4/5] log out date components for debugging --- PluginBinary/PluginBinary.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PluginBinary/PluginBinary.swift b/PluginBinary/PluginBinary.swift index 6db36f1..594d690 100644 --- a/PluginBinary/PluginBinary.swift +++ b/PluginBinary/PluginBinary.swift @@ -56,6 +56,9 @@ extension String: Error { } // 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 { From b9563b356954982aed230d3e1513c1395423d8f8 Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Mon, 29 Aug 2022 08:48:19 -0600 Subject: [PATCH 5/5] Use resources instead of compiler magic to access test calendar file --- Package.swift | 15 ++++++++++----- .../DoNotDisturbPluginTests.swift | 6 ++---- .../{ => Resources}/TestCal.ics | 0 3 files changed, 12 insertions(+), 9 deletions(-) rename Tests/DoNilDisturbPluginTests/{ => Resources}/TestCal.ics (100%) diff --git a/Package.swift b/Package.swift index 67d0585..92173c6 100644 --- a/Package.swift +++ b/Package.swift @@ -39,10 +39,15 @@ let package = Package( .target(name: "PluginBinary") ] ), - .testTarget(name: "DoNilDisturbPluginTests", - dependencies: [ - .target(name: "PluginBinary"), - .product(name: "iCalendar", package: "iCalendar") - ]) + .testTarget( + name: "DoNilDisturbPluginTests", + dependencies: [ + .target(name: "PluginBinary"), + .product(name: "iCalendar", package: "iCalendar") + ], + resources: [ + .copy("Resources"), + ] + ) ] ) diff --git a/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift b/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift index b07801e..31941cf 100644 --- a/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift +++ b/Tests/DoNilDisturbPluginTests/DoNotDisturbPluginTests.swift @@ -8,10 +8,8 @@ final class DoNotDisturbPluginTests: XCTestCase { func testHolidayLoad() throws { let date = Foundation.Calendar.current.date(from: DateComponents(year: 2022, month: 8, day: 30, hour: 13))! - let path = #filePath - let parent = (path as NSString).deletingLastPathComponent - let icalPath = parent.appending("/TestCal.ics") - let icalContents = try String(contentsOfFile: icalPath) + 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): diff --git a/Tests/DoNilDisturbPluginTests/TestCal.ics b/Tests/DoNilDisturbPluginTests/Resources/TestCal.ics similarity index 100% rename from Tests/DoNilDisturbPluginTests/TestCal.ics rename to Tests/DoNilDisturbPluginTests/Resources/TestCal.ics