macos: add some unit tests

This commit is contained in:
Mitchell Hashimoto
2025-12-29 06:25:47 -08:00
parent dbeeb952cc
commit 1b1ff3d76c
2 changed files with 252 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
import Testing
import AppKit
import CoreTransferable
import UniformTypeIdentifiers
@testable import Ghostty
struct TransferablePasteboardTests {
// MARK: - Test Helpers
/// A simple Transferable type for testing pasteboard conversion.
private struct DummyTransferable: Transferable, Equatable {
let payload: String
static var transferRepresentation: some TransferRepresentation {
DataRepresentation(contentType: .utf8PlainText) { value in
value.payload.data(using: .utf8)!
} importing: { data in
let string = String(data: data, encoding: .utf8)!
return DummyTransferable(payload: string)
}
}
}
/// A Transferable type that registers multiple content types.
private struct MultiTypeTransferable: Transferable {
let text: String
static var transferRepresentation: some TransferRepresentation {
DataRepresentation(contentType: .utf8PlainText) { value in
value.text.data(using: .utf8)!
} importing: { data in
MultiTypeTransferable(text: String(data: data, encoding: .utf8)!)
}
DataRepresentation(contentType: .plainText) { value in
value.text.data(using: .utf8)!
} importing: { data in
MultiTypeTransferable(text: String(data: data, encoding: .utf8)!)
}
}
}
// MARK: - Basic Functionality
@Test func pasteboardItemIsCreated() {
let transferable = DummyTransferable(payload: "hello")
let item = transferable.pasteboardItem()
#expect(item != nil)
}
@Test func pasteboardItemContainsExpectedType() {
let transferable = DummyTransferable(payload: "hello")
guard let item = transferable.pasteboardItem() else {
Issue.record("Expected pasteboard item to be created")
return
}
let expectedType = NSPasteboard.PasteboardType(UTType.utf8PlainText.identifier)
#expect(item.types.contains(expectedType))
}
@Test func pasteboardItemProvidesCorrectData() {
let transferable = DummyTransferable(payload: "test data")
guard let item = transferable.pasteboardItem() else {
Issue.record("Expected pasteboard item to be created")
return
}
let pasteboardType = NSPasteboard.PasteboardType(UTType.utf8PlainText.identifier)
// Write to a pasteboard to trigger data provider
let pasteboard = NSPasteboard(name: .init("test-\(UUID().uuidString)"))
pasteboard.clearContents()
pasteboard.writeObjects([item])
// Read back the data
guard let data = pasteboard.data(forType: pasteboardType) else {
Issue.record("Expected data to be available on pasteboard")
return
}
let string = String(data: data, encoding: .utf8)
#expect(string == "test data")
}
// MARK: - Multiple Content Types
@Test func multipleTypesAreRegistered() {
let transferable = MultiTypeTransferable(text: "multi")
guard let item = transferable.pasteboardItem() else {
Issue.record("Expected pasteboard item to be created")
return
}
let utf8Type = NSPasteboard.PasteboardType(UTType.utf8PlainText.identifier)
let plainType = NSPasteboard.PasteboardType(UTType.plainText.identifier)
#expect(item.types.contains(utf8Type))
#expect(item.types.contains(plainType))
}
@Test func multipleTypesProvideCorrectData() {
let transferable = MultiTypeTransferable(text: "shared content")
guard let item = transferable.pasteboardItem() else {
Issue.record("Expected pasteboard item to be created")
return
}
let pasteboard = NSPasteboard(name: .init("test-\(UUID().uuidString)"))
pasteboard.clearContents()
pasteboard.writeObjects([item])
// Both types should provide the same content
let utf8Type = NSPasteboard.PasteboardType(UTType.utf8PlainText.identifier)
let plainType = NSPasteboard.PasteboardType(UTType.plainText.identifier)
if let utf8Data = pasteboard.data(forType: utf8Type) {
#expect(String(data: utf8Data, encoding: .utf8) == "shared content")
}
if let plainData = pasteboard.data(forType: plainType) {
#expect(String(data: plainData, encoding: .utf8) == "shared content")
}
}
}

View File

@@ -0,0 +1,128 @@
import Testing
import Foundation
@testable import Ghostty
struct TerminalSplitDropZoneTests {
private let standardSize = CGSize(width: 100, height: 100)
// MARK: - Basic Edge Detection
@Test func topEdge() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 50, y: 5), in: standardSize)
#expect(zone == .top)
}
@Test func bottomEdge() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 50, y: 95), in: standardSize)
#expect(zone == .bottom)
}
@Test func leftEdge() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 5, y: 50), in: standardSize)
#expect(zone == .left)
}
@Test func rightEdge() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 95, y: 50), in: standardSize)
#expect(zone == .right)
}
// MARK: - Corner Tie-Breaking
// When distances are equal, the check order determines the result:
// left -> right -> top -> bottom
@Test func topLeftCornerSelectsLeft() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 0, y: 0), in: standardSize)
#expect(zone == .left)
}
@Test func topRightCornerSelectsRight() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 100, y: 0), in: standardSize)
#expect(zone == .right)
}
@Test func bottomLeftCornerSelectsLeft() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 0, y: 100), in: standardSize)
#expect(zone == .left)
}
@Test func bottomRightCornerSelectsRight() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 100, y: 100), in: standardSize)
#expect(zone == .right)
}
// MARK: - Center Point (All Distances Equal)
@Test func centerSelectsLeft() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 50, y: 50), in: standardSize)
#expect(zone == .left)
}
// MARK: - Non-Square Aspect Ratio
@Test func rectangularViewTopEdge() {
let size = CGSize(width: 200, height: 100)
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 100, y: 10), in: size)
#expect(zone == .top)
}
@Test func rectangularViewLeftEdge() {
let size = CGSize(width: 200, height: 100)
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 10, y: 50), in: size)
#expect(zone == .left)
}
@Test func tallRectangleTopEdge() {
let size = CGSize(width: 100, height: 200)
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 50, y: 10), in: size)
#expect(zone == .top)
}
// MARK: - Out-of-Bounds Points
@Test func pointLeftOfViewSelectsLeft() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: -10, y: 50), in: standardSize)
#expect(zone == .left)
}
@Test func pointAboveViewSelectsTop() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 50, y: -10), in: standardSize)
#expect(zone == .top)
}
@Test func pointRightOfViewSelectsRight() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 110, y: 50), in: standardSize)
#expect(zone == .right)
}
@Test func pointBelowViewSelectsBottom() {
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 50, y: 110), in: standardSize)
#expect(zone == .bottom)
}
// MARK: - Diagonal Regions (Triangular Zones)
@Test func upperLeftTriangleSelectsLeft() {
// Point in the upper-left triangle, closer to left than top
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 20, y: 30), in: standardSize)
#expect(zone == .left)
}
@Test func upperRightTriangleSelectsRight() {
// Point in the upper-right triangle, closer to right than top
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 80, y: 30), in: standardSize)
#expect(zone == .right)
}
@Test func lowerLeftTriangleSelectsLeft() {
// Point in the lower-left triangle, closer to left than bottom
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 20, y: 70), in: standardSize)
#expect(zone == .left)
}
@Test func lowerRightTriangleSelectsRight() {
// Point in the lower-right triangle, closer to right than bottom
let zone = TerminalSplitDropZone.calculate(at: CGPoint(x: 80, y: 70), in: standardSize)
#expect(zone == .right)
}
}