Files
clipbored/tests/clipboredtests/ClipboardPanelControllerTests.swift
2026-06-30 02:11:50 -07:00

174 lines
8.6 KiB
Swift

import XCTest
@testable import ClipBored
final class ClipboardPanelControllerTests: XCTestCase {
func testPanelFrameUsesFullWidthBottomShelf() {
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.minY, screenFrame.minY)
XCTAssertEqual(frames.shown.height, 408)
XCTAssertLessThan(frames.hidden.maxY, screenFrame.minY)
}
func testPanelFrameUsesVisibleFrameAroundDock() {
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)
XCTAssertEqual(frames.shown.minX, visibleFrame.minX)
XCTAssertEqual(frames.shown.maxX, visibleFrame.maxX)
XCTAssertEqual(frames.shown.minY, visibleFrame.minY)
XCTAssertEqual(frames.shown.height, 408)
}
func testPanelFrameSitsAboveVisibleBottomDock() {
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)
}
func testPanelFrameClampsTallDisplaysToShelfMaximum() {
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.minY, screenFrame.minY)
}
func testPanelFrameFitsTinyVisibleFrameWithoutOverflowing() {
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)
XCTAssertEqual(frames.shown.minY, visibleFrame.minY)
XCTAssertEqual(frames.shown.height, visibleFrame.height)
XCTAssertLessThan(frames.hidden.maxY, visibleFrame.minY)
}
func testPanelFramePlanningIsDeterministicAcrossRepeatedToggles() {
let screenFrame = CGRect(x: -1512, y: -120, width: 1512, height: 982)
let visibleFrame = CGRect(x: -1512, y: -24, width: 1512, height: 861)
let first = ClipboardPanelController.panelFrames(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
for _ in 0..<50 {
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)
}
}
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.easing, .easeInEaseOut)
}
func testReflowPlanMovesOpenPanelAboveNewBottomDockVisibleFrame() {
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.bottomSafeInset, 20)
}
func testReflowPlanTracksSideDockVisibleWidthWithoutBottomInsetInflation() {
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.bottomSafeInset, 18)
}
func testContentBottomInsetReservesBottomDockSpace() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 0, y: 96, width: 1512, height: 861)
let inset = ClipboardPanelController.contentBottomInset(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
XCTAssertEqual(inset, 20)
}
func testContentBottomInsetUsesMinimumWhenDockIsNotAtBottom() {
let screenFrame = CGRect(x: 0, y: 0, width: 1512, height: 982)
let visibleFrame = CGRect(x: 80, y: 0, width: 1432, height: 957)
let inset = ClipboardPanelController.contentBottomInset(forScreenFrame: screenFrame, visibleFrame: visibleFrame)
XCTAssertEqual(inset, 18)
}
func testCommandNumberShortcutsMapToCollections() {
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 18, modifiers: .command), .mostRecent)
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 19, modifiers: .command), .mostUsed)
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 20, modifiers: .command), .text)
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 21, modifiers: .command), .links)
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 23, modifiers: .command), .images)
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 22, modifiers: .command), .files)
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 26, modifiers: .command), .pinned)
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 28, modifiers: .command), .audio)
}
func testCollectionShortcutsRequireCommandOnlySoSearchTypingIsUntouched() {
XCTAssertNil(ClipboardPanelController.collectionShortcutMode(forKeyCode: 18, modifiers: []))
XCTAssertNil(ClipboardPanelController.collectionShortcutMode(forKeyCode: 18, modifiers: [.command, .shift]))
XCTAssertNil(ClipboardPanelController.collectionShortcutMode(forKeyCode: 29, modifiers: .command))
}
func testCommandActionShortcutsMapToSelectedClipActions() {
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 8, modifiers: .command), .copy)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 16, modifiers: .command), .preview)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 31, modifiers: .command), .open)
XCTAssertEqual(ClipboardPanelController.commandShortcutAction(forKeyCode: 15, modifiers: .command), .reveal)
}
func testCommandActionShortcutsRequireCommandOnlySoSearchTypingIsUntouched() {
XCTAssertNil(ClipboardPanelController.commandShortcutAction(forKeyCode: 8, modifiers: []))
XCTAssertNil(ClipboardPanelController.commandShortcutAction(forKeyCode: 8, modifiers: [.command, .shift]))
XCTAssertNil(ClipboardPanelController.commandShortcutAction(forKeyCode: 9, modifiers: .command))
}
func testModifiedShortcutsMapToPlainTextActions() {
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 1, modifiers: [.command, .shift]), .toggleStack)
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 8, modifiers: [.command, .shift]), .copyPlainText)
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 9, modifiers: [.command, .shift]), .pastePlainText)
XCTAssertEqual(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 36, modifiers: [.command, .shift]), .pasteStackNext)
}
func testModifiedShortcutsRequireCommandShiftOnly() {
XCTAssertNil(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 8, modifiers: .command))
XCTAssertNil(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 8, modifiers: [.command, .option, .shift]))
XCTAssertNil(ClipboardPanelController.modifiedShortcutAction(forKeyCode: 31, modifiers: [.command, .shift]))
}
}