UI fixes
Some checks failed
CI / Test And Build (push) Has been cancelled

This commit is contained in:
Akshay Kolli
2026-07-08 01:13:02 -04:00
parent c7316105c7
commit d86d392c3a
46 changed files with 17543 additions and 1561 deletions

View File

@@ -1,16 +1,80 @@
import AppKit
import XCTest
@testable import ClipBored
final class ClipboardPanelControllerTests: XCTestCase {
func testPanelFrameUsesFullWidthBottomShelf() {
private var tempURLs: [URL] = []
private var defaultsSuites: [String] = []
override func tearDown() {
for url in tempURLs {
try? FileManager.default.removeItem(at: url)
}
tempURLs.removeAll()
for suite in defaultsSuites {
UserDefaults(suiteName: suite)?.removePersistentDomain(forName: suite)
}
defaultsSuites.removeAll()
super.tearDown()
}
func testPanelFrameUsesRightSideShelfByDefault() {
let screenFrame = CGRect(x: -1200, y: -200, width: 1200, height: 800)
let frames = ClipboardPanelController.panelFrames(forScreenFrame: screenFrame, visibleFrame: screenFrame)
XCTAssertEqual(frames.shown.minX, screenFrame.minX)
XCTAssertEqual(frames.shown.maxX, screenFrame.maxX)
XCTAssertEqual(frames.shown.width, 336)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.height, 408)
XCTAssertLessThan(frames.hidden.maxY, screenFrame.minY)
XCTAssertEqual(frames.shown.maxY, screenFrame.maxY)
XCTAssertEqual(frames.hidden.minX, screenFrame.maxX + 1)
XCTAssertEqual(frames.hidden.minY, frames.shown.minY)
}
func testOpenScreenSelectionUsesStatusClickScreenWhenProvided() {
XCTAssertEqual(
ClipboardPanelController.selectedOpenScreen(
explicit: "status-item-screen",
preferred: nil,
pointer: "pointer-screen",
fallback: "fallback-screen"
),
"status-item-screen"
)
}
func testOpenScreenSelectionFallsBackToPointerForGlobalShortcut() {
XCTAssertEqual(
ClipboardPanelController.selectedOpenScreen(
explicit: Optional<String>.none,
preferred: nil,
pointer: "pointer-screen",
fallback: "fallback-screen"
),
"pointer-screen"
)
}
func testReflowScreenSelectionKeepsCurrentPanelScreenAheadOfPointer() {
XCTAssertEqual(
ClipboardPanelController.selectedReflowScreen(
currentPanel: "current-panel-screen",
lastKnown: "last-known-screen",
preferred: nil,
pointer: "pointer-screen",
fallback: "fallback-screen"
),
"current-panel-screen"
)
XCTAssertEqual(
ClipboardPanelController.selectedReflowScreen(
currentPanel: Optional<String>.none,
lastKnown: "last-known-screen",
preferred: nil,
pointer: "pointer-screen",
fallback: "fallback-screen"
),
"last-known-screen"
)
}
func testPanelFrameUsesVisibleFrameAroundDock() {
@@ -19,33 +83,48 @@ final class ClipboardPanelControllerTests: XCTestCase {
let frames = ClipboardPanelController.panelFrames(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
XCTAssertEqual(frames.shown.minX, visibleFrame.minX)
XCTAssertEqual(frames.shown.maxX, visibleFrame.maxX)
XCTAssertEqual(frames.shown.minY, visibleFrame.minY)
XCTAssertEqual(frames.shown.height, 408)
XCTAssertEqual(frames.shown.minX, visibleFrame.maxX - 336)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.maxY, visibleFrame.maxY)
XCTAssertEqual(frames.shown.width, 336)
}
func testPanelFrameSitsAboveVisibleBottomDock() {
func testPanelFrameUsesAvailableHeightWhenBottomDockIsVisible() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 0, y: 96, width: 1512, height: 861)
let frames = ClipboardPanelController.panelFrames(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
XCTAssertEqual(frames.shown.minX, visibleFrame.minX)
XCTAssertEqual(frames.shown.maxX, visibleFrame.maxX)
XCTAssertEqual(frames.shown.minY, visibleFrame.minY)
XCTAssertEqual(frames.shown.height, 408)
XCTAssertLessThan(frames.hidden.maxY, visibleFrame.minY)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.maxY, visibleFrame.maxY)
XCTAssertEqual(frames.shown.width, 336)
XCTAssertEqual(frames.hidden.minX, visibleFrame.maxX + 1)
}
func testPanelFrameClampsTallDisplaysToShelfMaximum() {
func testPanelFrameTouchesScreenBottomWhenBottomDockIsAutoHidden() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 0, y: 4, width: 1512, height: 953)
let frames = ClipboardPanelController.panelFrames(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
XCTAssertEqual(frames.shown.maxX, visibleFrame.maxX)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.maxY, visibleFrame.maxY)
XCTAssertEqual(frames.shown.width, 336)
XCTAssertEqual(frames.hidden.minX, visibleFrame.maxX + 1)
}
func testPanelFrameKeepsSideShelfWidthOnTallDisplays() {
let screenFrame = CGRect(x: 0, y: 0, width: 3008, height: 2000)
let frames = ClipboardPanelController.panelFrames(forScreenFrame: screenFrame, visibleFrame: screenFrame)
XCTAssertEqual(frames.shown.width, 3008)
XCTAssertEqual(frames.shown.height, 430)
XCTAssertEqual(frames.shown.width, 336)
XCTAssertEqual(frames.shown.height, 2000)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.maxX, screenFrame.maxX)
}
func testPanelFrameFitsTinyVisibleFrameWithoutOverflowing() {
@@ -54,9 +133,64 @@ final class ClipboardPanelControllerTests: XCTestCase {
let frames = ClipboardPanelController.panelFrames(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
XCTAssertEqual(frames.shown.minY, visibleFrame.minY)
XCTAssertEqual(frames.shown.height, visibleFrame.height)
XCTAssertLessThan(frames.hidden.maxY, visibleFrame.minY)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.maxY, visibleFrame.maxY)
XCTAssertEqual(frames.shown.width, 320)
XCTAssertLessThanOrEqual(frames.shown.width, visibleFrame.width)
XCTAssertEqual(frames.hidden.minX, screenFrame.maxX + 1)
}
func testPanelFrameIgnoresLegacyPreferredResizableHeight() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 0, y: 96, width: 1512, height: 861)
let frames = ClipboardPanelController.panelFrames(
forScreenFrame: screenFrame,
visibleFrame: visibleFrame,
preferredHeight: 600
)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.maxY, visibleFrame.maxY)
XCTAssertEqual(frames.shown.height, 957)
XCTAssertEqual(frames.hidden.minX, visibleFrame.maxX + 1)
}
func testPanelFrameLegacyPreferredHeightDoesNotAffectSideShelf() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let tooTall = ClipboardPanelController.panelFrames(
forScreenFrame: screenFrame,
visibleFrame: visibleFrame,
preferredHeight: 900
)
let tooShort = ClipboardPanelController.panelFrames(
forScreenFrame: screenFrame,
visibleFrame: visibleFrame,
preferredHeight: 120
)
XCTAssertEqual(tooTall.shown.height, 982)
XCTAssertEqual(tooShort.shown.height, 982)
XCTAssertEqual(tooTall.shown.width, 336)
XCTAssertEqual(tooShort.shown.width, 336)
}
func testPanelFrameLegacyPreferredHeightDoesNotOverflowTinyVisibleFrame() {
let screenFrame = CGRect(x: 0, y: 0, width: 640, height: 320)
let visibleFrame = CGRect(x: 0, y: 48, width: 640, height: 220)
let frames = ClipboardPanelController.panelFrames(
forScreenFrame: screenFrame,
visibleFrame: visibleFrame,
preferredHeight: 620
)
XCTAssertEqual(frames.shown.height, 268)
XCTAssertEqual(frames.shown.width, 320)
XCTAssertLessThanOrEqual(frames.shown.height, visibleFrame.maxY - screenFrame.minY)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
}
func testPanelFramePlanningIsDeterministicAcrossRepeatedToggles() {
@@ -68,48 +202,161 @@ final class ClipboardPanelControllerTests: XCTestCase {
let frames = ClipboardPanelController.panelFrames(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
XCTAssertEqual(frames.shown, first.shown)
XCTAssertEqual(frames.hidden, first.hidden)
XCTAssertEqual(frames.hidden.maxY, frames.shown.minY - 1)
XCTAssertEqual(frames.hidden.minX, frames.shown.maxX + 1)
}
}
func testPanelAnimationProfileStaysShortForSixtyFpsFeel() {
let profile = ClipboardPanelController.animationProfile
XCTAssertEqual(profile.showDuration, 0.16)
XCTAssertEqual(profile.hideDuration, 0.12)
XCTAssertEqual(profile.reflowDuration, 0.10)
XCTAssertLessThanOrEqual(profile.showDuration * 60, 10)
XCTAssertLessThanOrEqual(profile.hideDuration * 60, 8)
XCTAssertLessThanOrEqual(profile.reflowDuration * 60, 6)
XCTAssertEqual(profile.showDuration, 0.22)
XCTAssertEqual(profile.hideDuration, 0.16)
XCTAssertEqual(profile.reflowDuration, 0.18)
XCTAssertLessThanOrEqual(profile.showDuration * 60, 14)
XCTAssertLessThanOrEqual(profile.hideDuration * 60, 10)
XCTAssertLessThanOrEqual(profile.reflowDuration * 60, 11)
XCTAssertEqual(profile.easing, .easeInEaseOut)
}
func testReflowPlanMovesOpenPanelAboveNewBottomDockVisibleFrame() {
func testPanelCollectionBehaviorStaysLocalToActiveSpaceAndSupportsFullscreen() {
let behavior = ClipboardPanelController.panelCollectionBehavior
XCTAssertTrue(behavior.contains(.moveToActiveSpace))
XCTAssertTrue(behavior.contains(.fullScreenAuxiliary))
XCTAssertTrue(behavior.contains(.transient))
XCTAssertFalse(behavior.contains(.canJoinAllSpaces))
}
func testShowingPanelClearsAndCollapsesStaleSearchState() throws {
let screen = try XCTUnwrap(NSScreen.screens.first)
let (controller, _) = makeController(preferredScreen: screen)
controller.debugSetSearchFieldText("stale query")
drainMainQueue()
XCTAssertEqual(controller.debugSearchFieldText, "stale query")
XCTAssertEqual(controller.debugSearchFieldWidth, 164, accuracy: 0.5)
XCTAssertEqual(controller.debugSearchFieldPlaceholderText, "Search clips")
XCTAssertTrue(controller.debugSearchFieldIsVisible)
XCTAssertFalse(controller.debugSearchIconButtonIsVisible)
controller.show(preferredScreen: screen)
defer { controller.hide(immediate: true) }
drainMainQueue()
XCTAssertEqual(controller.debugSearchFieldText, "")
XCTAssertEqual(controller.debugSearchFieldWidth, 30, accuracy: 1)
XCTAssertEqual(controller.debugSearchFieldPlaceholderText, "")
XCTAssertFalse(controller.debugSearchFieldIsVisible)
XCTAssertTrue(controller.debugSearchIconButtonIsVisible)
XCTAssertFalse(controller.debugIsSearchFieldEditing)
}
func testReflowPlanKeepsOpenPanelOnRightSideWhenBottomDockIsVisible() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 0, y: 112, width: 1512, height: 845)
let plan = ClipboardPanelController.reflowPlan(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
XCTAssertEqual(plan.frame.minX, visibleFrame.minX)
XCTAssertEqual(plan.frame.maxX, visibleFrame.maxX)
XCTAssertEqual(plan.frame.minY, visibleFrame.minY)
XCTAssertEqual(plan.frame.height, 408)
XCTAssertEqual(plan.frame.minY, screenFrame.minY)
XCTAssertEqual(plan.frame.maxY, visibleFrame.maxY)
XCTAssertEqual(plan.frame.width, 336)
XCTAssertEqual(plan.bottomSafeInset, 20)
}
func testReflowPlanTracksSideDockVisibleWidthWithoutBottomInsetInflation() {
func testReflowPlanTouchesScreenBottomWhenBottomDockIsAutoHidden() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 0, y: 4, width: 1512, height: 953)
let plan = ClipboardPanelController.reflowPlan(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
XCTAssertEqual(plan.frame.maxX, visibleFrame.maxX)
XCTAssertEqual(plan.frame.minY, screenFrame.minY)
XCTAssertEqual(plan.frame.maxY, visibleFrame.maxY)
XCTAssertEqual(plan.frame.width, 336)
XCTAssertEqual(plan.bottomSafeInset, 18)
}
func testReflowPlanIgnoresLegacyPreferredResizableHeight() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 0, y: 96, width: 1512, height: 861)
let plan = ClipboardPanelController.reflowPlan(
forScreenFrame: screenFrame,
visibleFrame: visibleFrame,
preferredHeight: 600
)
XCTAssertEqual(plan.frame.minY, screenFrame.minY)
XCTAssertEqual(plan.frame.height, 957)
XCTAssertEqual(plan.frame.width, 336)
XCTAssertEqual(plan.bottomSafeInset, 20)
}
func testReflowPlanTracksSideDockVisibleFrameWithoutBottomInsetInflation() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 86, y: 0, width: 1426, height: 957)
let plan = ClipboardPanelController.reflowPlan(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
XCTAssertEqual(plan.frame.minX, visibleFrame.minX)
XCTAssertEqual(plan.frame.maxX, visibleFrame.maxX)
XCTAssertEqual(plan.frame.minY, visibleFrame.minY)
XCTAssertEqual(plan.frame.height, 408)
XCTAssertEqual(plan.frame.minX, visibleFrame.maxX - 336)
XCTAssertEqual(plan.frame.minY, screenFrame.minY)
XCTAssertEqual(plan.frame.height, 957)
XCTAssertEqual(plan.bottomSafeInset, 18)
}
func testPanelFrameUsesConfiguredRightSideShelf() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 0, y: 96, width: 1512, height: 861)
let frames = ClipboardPanelController.panelFrames(
forScreenFrame: screenFrame,
visibleFrame: visibleFrame,
side: .right
)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.maxY, visibleFrame.maxY)
XCTAssertEqual(frames.shown.maxX, visibleFrame.maxX)
XCTAssertEqual(frames.shown.width, 336)
XCTAssertEqual(frames.hidden.minY, frames.shown.minY)
XCTAssertEqual(frames.hidden.minX, screenFrame.maxX + 1)
}
func testPanelFrameUsesConfiguredLeftSideShelf() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 80, y: 0, width: 1432, height: 957)
let frames = ClipboardPanelController.panelFrames(
forScreenFrame: screenFrame,
visibleFrame: visibleFrame,
side: .left
)
XCTAssertEqual(frames.shown.minX, visibleFrame.minX)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.maxY, visibleFrame.maxY)
XCTAssertEqual(frames.shown.width, 336)
XCTAssertEqual(frames.hidden.maxX, visibleFrame.minX - 1)
XCTAssertEqual(frames.hidden.minY, frames.shown.minY)
}
func testPanelFrameUsesFullScreenHeightWhenVisibleFrameMatchesScreen() {
let screenFrame = CGRect(x: -1512, y: -120, width: 1512, height: 982)
let frames = ClipboardPanelController.panelFrames(
forScreenFrame: screenFrame,
visibleFrame: screenFrame,
side: .right
)
XCTAssertEqual(frames.shown.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.maxY, screenFrame.maxY)
XCTAssertEqual(frames.shown.maxX, screenFrame.maxX)
XCTAssertEqual(frames.shown.width, 336)
}
func testContentBottomInsetReservesBottomDockSpace() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 0, y: 96, width: 1512, height: 861)
@@ -128,6 +375,24 @@ final class ClipboardPanelControllerTests: XCTestCase {
XCTAssertEqual(inset, 18)
}
func testPanelSharingTypeHidesWindowFromScreenCaptureWhenEnabled() {
XCTAssertEqual(ClipboardPanelController.panelSharingType(hideFromScreenCapture: false), .readOnly)
XCTAssertEqual(ClipboardPanelController.panelSharingType(hideFromScreenCapture: true), .none)
}
func testLinkPreviewFrameSitsAboveBottomShelfWhenSpaceAllows() {
let visibleFrame = NSRect(x: 0, y: 0, width: 1512, height: 982)
let shelfFrame = NSRect(x: 0, y: 0, width: 1512, height: 408)
let frame = LinkPreviewWindowController.previewFrame(parentFrame: shelfFrame, visibleFrame: visibleFrame)
XCTAssertGreaterThanOrEqual(frame.minY, shelfFrame.maxY + 14)
XCTAssertLessThanOrEqual(frame.maxY, visibleFrame.maxY - 24)
XCTAssertEqual(frame.width, 1088)
XCTAssertEqual(frame.height, 536)
XCTAssertEqual(frame.midX, shelfFrame.midX, accuracy: 0.5)
}
func testCommandNumberShortcutsMapToQuickPasteSlots() {
XCTAssertEqual(ClipboardPanelController.quickPasteIndex(forKeyCode: 18, modifiers: .command), 0)
XCTAssertEqual(ClipboardPanelController.quickPasteIndex(forKeyCode: 19, modifiers: .command), 1)
@@ -181,20 +446,48 @@ final class ClipboardPanelControllerTests: XCTestCase {
XCTAssertEqual(ClipboardPanelController.navigationShortcutAction(forKeyCode: 121, modifiers: []), .pageNext)
XCTAssertEqual(ClipboardPanelController.navigationShortcutAction(forKeyCode: 116, modifiers: []), .pagePrevious)
XCTAssertEqual(ClipboardPanelController.navigationShortcutAction(forKeyCode: 123, modifiers: []), .previous)
XCTAssertEqual(ClipboardPanelController.navigationShortcutAction(forKeyCode: 126, modifiers: .command), .first)
XCTAssertEqual(ClipboardPanelController.navigationShortcutAction(forKeyCode: 125, modifiers: .command), .last)
}
func testNavigationShortcutsRequireNoModifiers() {
func testNavigationShortcutsRejectUnsupportedModifiers() {
XCTAssertNil(ClipboardPanelController.navigationShortcutAction(forKeyCode: 124, modifiers: .command))
XCTAssertNil(ClipboardPanelController.navigationShortcutAction(forKeyCode: 126, modifiers: []))
XCTAssertNil(ClipboardPanelController.navigationShortcutAction(forKeyCode: 125, modifiers: []))
XCTAssertNil(ClipboardPanelController.navigationShortcutAction(forKeyCode: 121, modifiers: .shift))
XCTAssertNil(ClipboardPanelController.navigationShortcutAction(forKeyCode: 35, modifiers: []))
}
func testSelectionShortcutsMapToRangeAndSelectAllActions() {
XCTAssertEqual(ClipboardPanelController.selectionShortcutAction(forKeyCode: 0, modifiers: .command), .selectAll)
XCTAssertEqual(ClipboardPanelController.selectionShortcutAction(forKeyCode: 115, modifiers: .shift), .extendFirst)
XCTAssertEqual(ClipboardPanelController.selectionShortcutAction(forKeyCode: 119, modifiers: .shift), .extendLast)
XCTAssertEqual(ClipboardPanelController.selectionShortcutAction(forKeyCode: 124, modifiers: .shift), .extendNext)
XCTAssertEqual(ClipboardPanelController.selectionShortcutAction(forKeyCode: 121, modifiers: .shift), .extendPageNext)
XCTAssertEqual(ClipboardPanelController.selectionShortcutAction(forKeyCode: 116, modifiers: .shift), .extendPagePrevious)
XCTAssertEqual(ClipboardPanelController.selectionShortcutAction(forKeyCode: 123, modifiers: .shift), .extendPrevious)
}
func testSelectionShortcutsRequireExactModifierSets() {
XCTAssertNil(ClipboardPanelController.selectionShortcutAction(forKeyCode: 0, modifiers: []))
XCTAssertNil(ClipboardPanelController.selectionShortcutAction(forKeyCode: 0, modifiers: [.command, .shift]))
XCTAssertNil(ClipboardPanelController.selectionShortcutAction(forKeyCode: 124, modifiers: []))
XCTAssertNil(ClipboardPanelController.selectionShortcutAction(forKeyCode: 124, modifiers: [.command, .shift]))
}
func testCommandActionShortcutsMapToSelectedClipActions() {
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 8, modifiers: .command), .copy)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 14, modifiers: .command), .edit)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 3, modifiers: .command), .focusSearch)
XCTAssertNil(ClipboardPanelController.commandShortcutAction(forKeyCode: 45, modifiers: .command))
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 5, modifiers: .command), .showInClipboard)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 16, modifiers: .command), .preview)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 31, modifiers: .command), .open)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 15, modifiers: .command), .reveal)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 15, modifiers: .command), .rename)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 17, modifiers: .command), .toggleCapturePause)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 6, modifiers: .command), .undoDelete)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 123, modifiers: .command), .previousCollection)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 124, modifiers: .command), .nextCollection)
}
func testCommandActionShortcutsRequireCommandOnlySoSearchTypingIsUntouched() {
@@ -203,17 +496,68 @@ final class ClipboardPanelControllerTests: XCTestCase {
XCTAssertNil(ClipboardPanelController.commandShortcutAction(forKeyCode: 9, modifiers: .command))
}
func testModifiedShortcutsMapToPlainTextActions() {
func testModifiedShortcutsMapToPanelActions() {
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 36, modifiers: .shift), .pastePlainText)
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 1, modifiers: [.command, .shift]), .toggleStack)
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 8, modifiers: [.command, .shift]), .copyPlainText)
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 8, modifiers: [.command, .shift]), .toggleStackCapture)
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 9, modifiers: [.command, .shift]), .pastePlainText)
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 45, modifiers: [.command, .shift]), .newCollection)
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 36, modifiers: [.command, .shift]), .pasteStackNext)
}
func testModifiedShortcutsRequireCommandShiftOnly() {
XCTAssertNil(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 36, modifiers: []))
XCTAssertNil(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 8, modifiers: .shift))
XCTAssertNil(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 8, modifiers: .command))
XCTAssertNil(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 8, modifiers: [.command, .option, .shift]))
XCTAssertNil(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 31, modifiers: [.command, .shift]))
}
private func makeController(preferredScreen: NSScreen) -> (ClipboardPanelController, ClipboardStore) {
let settings = makeSettings()
let encryptionService = ClipboardEncryptionService(keyProvider: { nil })
let cacheService = ClipboardCacheService(
baseURL: makeTempDirectory(),
encryptionService: encryptionService
)
let store = ClipboardStore(
settings: settings,
cacheService: cacheService,
baseURL: makeTempDirectory(),
encryptionService: encryptionService
)
let controller = ClipboardPanelController(
store: store,
settings: settings,
cacheService: cacheService,
preferredScreen: { preferredScreen }
)
return (controller, store)
}
private func makeSettings() -> SettingsModel {
let suite = "com.clipbored.controllertest.\(UUID().uuidString)"
defaultsSuites.append(suite)
let defaults = UserDefaults(suiteName: suite)!
let settings = SettingsModel(defaults: defaults)
settings.maxHistoryItems = 10
settings.historyRetention = .forever
settings.pruneDuplicates = false
return settings
}
private func makeTempDirectory() -> URL {
let directory = FileManager.default.temporaryDirectory
.appendingPathComponent("clipbored-controllertest")
.appendingPathComponent(UUID().uuidString)
try? FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
tempURLs.append(directory)
return directory
}
private func drainMainQueue() {
for _ in 0..<24 {
RunLoop.main.run(until: Date().addingTimeInterval(0.01))
}
}
}