diff --git a/Clocker/ClockerUnitTests/StandardMenubarHandlerTests.swift b/Clocker/ClockerUnitTests/StandardMenubarHandlerTests.swift index 1eae0a7..4d18c8d 100644 --- a/Clocker/ClockerUnitTests/StandardMenubarHandlerTests.swift +++ b/Clocker/ClockerUnitTests/StandardMenubarHandlerTests.swift @@ -2,10 +2,13 @@ import CoreModelKit import XCTest +import EventKit @testable import Clocker class StandardMenubarHandlerTests: XCTestCase { + private let eventStore = EKEventStore() + private let mumbai = ["customLabel": "Ghar", "formattedAddress": "Mumbai", "place_id": "ChIJwe1EZjDG5zsRaYxkjY_tpF0", @@ -113,4 +116,73 @@ class StandardMenubarHandlerTests: XCTestCase { let menubarHandler = MenubarTitleProvider(with: store) XCTAssertNotNil(menubarHandler.titleForMenubar()) } + + func testFormattedUpcomingEvent() { + let store = makeMockStore() + + let futureChunk = TimeChunk(seconds: 10, minutes: 10, hours: 0, days: 0, weeks: 0, months: 0, years: 0) + let mockEvent = EKEvent(eventStore: eventStore) + mockEvent.title = "Mock Title" + mockEvent.startDate = Date().add(futureChunk) + + let menubarHandler = MenubarTitleProvider(with: store) + XCTAssert(menubarHandler.format(event: mockEvent) == "Mock Title in 10m", + "Suffix \(menubarHandler.format(event: mockEvent)) doesn't match expectation") + + } + + func testUpcomingEventHappeningWithinOneMinute() { + let store = makeMockStore() + + let futureChunk = TimeChunk(seconds: 10, minutes: 1, hours: 0, days: 0, weeks: 0, months: 0, years: 0) + let mockEvent = EKEvent(eventStore: eventStore) + mockEvent.title = "Mock Title" + mockEvent.startDate = Date().add(futureChunk) + + let menubarHandler = MenubarTitleProvider(with: store) + XCTAssert(menubarHandler.format(event: mockEvent) == "Mock Title in 1m", + "Suffix \(menubarHandler.format(event: mockEvent)) doesn't match expectation") + + } + + func testUpcomingEventHappeningWithinSeconds() { + let store = makeMockStore() + + let futureChunk = TimeChunk(seconds: 10, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) + let mockEvent = EKEvent(eventStore: eventStore) + mockEvent.title = "Mock Title" + mockEvent.startDate = Date().add(futureChunk) + + let menubarHandler = MenubarTitleProvider(with: store) + XCTAssert(menubarHandler.format(event: mockEvent) == "Mock Title starts now.", + "Suffix \(menubarHandler.format(event: mockEvent)) doesn't match expectation") + + } + + func testEmptyUpcomingEvent() { + let store = makeMockStore() + + let futureChunk = TimeChunk(seconds: 10, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) + let mockEvent = EKEvent(eventStore: eventStore) + mockEvent.startDate = Date().add(futureChunk) + + let menubarHandler = MenubarTitleProvider(with: store) + XCTAssert(menubarHandler.format(event: mockEvent) == CLEmptyString, + "Suffix \(menubarHandler.format(event: mockEvent)) doesn't match expectation") + + } + + func testLongUpcomingEvent() { + let store = makeMockStore() + + let futureChunk = TimeChunk(seconds: 10, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) + let mockEvent = EKEvent(eventStore: eventStore) + mockEvent.title = "Really long calendar event title that longer than the longest name" + mockEvent.startDate = Date().add(futureChunk) + + let menubarHandler = MenubarTitleProvider(with: store) + XCTAssert(menubarHandler.format(event: mockEvent) == "Really long calendar event tit... starts now.", + "Suffix \(menubarHandler.format(event: mockEvent)) doesn't match expectation") + + } } diff --git a/Clocker/Events and Reminders/CalendarHandler.swift b/Clocker/Events and Reminders/CalendarHandler.swift index fc0ba39..bc1e8a2 100644 --- a/Clocker/Events and Reminders/CalendarHandler.swift +++ b/Clocker/Events and Reminders/CalendarHandler.swift @@ -116,40 +116,6 @@ extension EventCenter { return (formattedTitle, menubarText) } - func format(event: EKEvent) -> String { - guard let truncateLength = DataStore.shared().retrieve(key: CLTruncateTextLength) as? NSNumber, let eventTitle = event.title else { - return CLEmptyString - } - - let seconds = event.startDate.timeIntervalSinceNow - - var menubarText: String = CLEmptyString - - if eventTitle.count > truncateLength.intValue { - let truncateIndex = eventTitle.index(eventTitle.startIndex, offsetBy: truncateLength.intValue) - let truncatedTitle = String(eventTitle[.. 2 { - let suffix = String(format: " in %0.f mins", minutes) - menubarText.append(suffix) - } else if minutes == 1 { - let suffix = String(format: " in %0.f min", minutes) - menubarText.append(suffix) - } else { - menubarText.append(" starts now.") - } - - return menubarText - } - func nextOccuring(_: [EventInfo]) -> EventInfo? { if calendarAccessDenied() || calendarAccessNotDetermined() { return nil diff --git a/Clocker/Preferences/Menu Bar/MenubarTitleProvider.swift b/Clocker/Preferences/Menu Bar/MenubarTitleProvider.swift index 2134f14..04da071 100644 --- a/Clocker/Preferences/Menu Bar/MenubarTitleProvider.swift +++ b/Clocker/Preferences/Menu Bar/MenubarTitleProvider.swift @@ -60,11 +60,41 @@ class MenubarTitleProvider: NSObject { continue } - return EventCenter.sharedCenter().format(event: event) + return format(event: event) } } } return nil } + + internal func format(event: EKEvent) -> String { + guard let truncateLength = store.retrieve(key: CLTruncateTextLength) as? NSNumber, let eventTitle = event.title, event.title.isEmpty == false else { + return CLEmptyString + } + + let seconds = event.startDate.timeIntervalSinceNow + + var menubarText: String = CLEmptyString + + if eventTitle.count > truncateLength.intValue { + let truncateIndex = eventTitle.index(eventTitle.startIndex, offsetBy: truncateLength.intValue) + let truncatedTitle = String(eventTitle[..= 1 { + let suffix = String(format: " in %0.fm", minutes) + menubarText.append(suffix) + } else { + menubarText.append(" starts now.") + } + + return menubarText + } }