Skip to content

Commit 6899ad3

Browse files
committed
Add more tests
1 parent 1483b09 commit 6899ad3

2 files changed

Lines changed: 145 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//
2+
// KittyKeyboardAppKitReproductionTests.swift
3+
//
4+
// AppKit integration coverage for issue #624. Enable this suite with:
5+
// RUN_APPKIT_TESTS=1 swift test --filter KittyKeyboardAppKitReproductionTests
6+
//
7+
8+
#if os(macOS)
9+
import AppKit
10+
import Foundation
11+
import Testing
12+
@testable import SwiftTerm
13+
14+
private func appKitTestsEnabled() -> Bool {
15+
ProcessInfo.processInfo.environment["RUN_APPKIT_TESTS"] == "1"
16+
}
17+
18+
@Suite(.enabled(if: appKitTestsEnabled()))
19+
@MainActor
20+
final class KittyKeyboardAppKitReproductionTests {
21+
private final class CapturingDelegate: TerminalViewDelegate {
22+
var sent: [UInt8] = []
23+
24+
func send(source: TerminalView, data: ArraySlice<UInt8>) {
25+
sent.append(contentsOf: data)
26+
}
27+
28+
func sizeChanged(source: TerminalView, newCols: Int, newRows: Int) {}
29+
func setTerminalTitle(source: TerminalView, title: String) {}
30+
func hostCurrentDirectoryUpdate(source: TerminalView, directory: String?) {}
31+
func scrolled(source: TerminalView, position: Double) {}
32+
func requestOpenLink(source: TerminalView, link: String, params: [String: String]) {}
33+
func bell(source: TerminalView) {}
34+
func clipboardCopy(source: TerminalView, content: Data) {}
35+
func clipboardRead(source: TerminalView) -> Data? { nil }
36+
func iTermContent(source: TerminalView, content: ArraySlice<UInt8>) {}
37+
func rangeChanged(source: TerminalView, startY: Int, endY: Int) {}
38+
}
39+
40+
private func press(flags: Int,
41+
characters: String,
42+
charactersIgnoringModifiers: String,
43+
keyCode: UInt16) -> [UInt8] {
44+
_ = NSApplication.shared
45+
46+
let view = TerminalView(frame: CGRect(x: 0, y: 0, width: 400, height: 200))
47+
let capture = CapturingDelegate()
48+
view.terminalDelegate = capture
49+
view.feed(text: "\u{1b}[>\(flags)u")
50+
51+
let window = NSWindow(contentRect: view.frame,
52+
styleMask: [.titled],
53+
backing: .buffered,
54+
defer: false)
55+
window.contentView?.addSubview(view)
56+
window.makeFirstResponder(view)
57+
capture.sent.removeAll()
58+
59+
let event = NSEvent.keyEvent(
60+
with: .keyDown,
61+
location: .zero,
62+
modifierFlags: [.shift],
63+
timestamp: ProcessInfo.processInfo.systemUptime,
64+
windowNumber: window.windowNumber,
65+
context: nil,
66+
characters: characters,
67+
charactersIgnoringModifiers: charactersIgnoringModifiers,
68+
isARepeat: false,
69+
keyCode: keyCode
70+
)!
71+
view.keyDown(with: event)
72+
return capture.sent
73+
}
74+
75+
@Test func reportAlternatesDoesNotConvertTextProducingKeysToCSIU() {
76+
for flags in [5, 7] { // disambiguate + reportAlternates, with optional reportEvents
77+
#expect(press(flags: flags,
78+
characters: "E",
79+
charactersIgnoringModifiers: "e",
80+
keyCode: 14) == Array("E".utf8))
81+
#expect(press(flags: flags,
82+
characters: "é",
83+
charactersIgnoringModifiers: "è",
84+
keyCode: 33) == Array("é".utf8))
85+
}
86+
}
87+
}
88+
#endif
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#if os(macOS)
2+
import Foundation
3+
import Testing
4+
5+
@testable import SwiftTerm
6+
7+
@Suite("Mac default link handling")
8+
struct MacDefaultLinkTests {
9+
@Test func keepsExplicitURL() throws {
10+
let expected = try #require(URL(string: "https://example.com/path"))
11+
12+
#expect(TerminalView.defaultLinkURL(expected.absoluteString) == expected)
13+
}
14+
15+
@Test func createsFileURLForExistingPathWithSpaces() throws {
16+
try withTemporaryFile(named: "file with spaces.txt") { fileURL in
17+
#expect(TerminalView.defaultLinkURL(fileURL.path) == fileURL)
18+
}
19+
}
20+
21+
@Test func removesLineAndColumnLocation() throws {
22+
try withTemporaryFile(named: "source.swift") { fileURL in
23+
#expect(TerminalView.defaultLinkURL("\(fileURL.path):42") == fileURL)
24+
#expect(TerminalView.defaultLinkURL("\(fileURL.path):42:10") == fileURL)
25+
}
26+
}
27+
28+
@Test func keepsExistingFilenameThatEndsWithLocationSyntax() throws {
29+
try withTemporaryFile(named: "source.swift:42") { fileURL in
30+
#expect(TerminalView.defaultLinkURL(fileURL.path) == fileURL)
31+
}
32+
}
33+
34+
@Test func rejectsMissingFile() {
35+
let path = FileManager.default.temporaryDirectory
36+
.appendingPathComponent(UUID().uuidString)
37+
.path
38+
39+
#expect(TerminalView.defaultLinkURL(path) == nil)
40+
#expect(TerminalView.defaultLinkURL("\(path):42:10") == nil)
41+
}
42+
43+
private func withTemporaryFile(
44+
named name: String,
45+
body: (URL) throws -> Void
46+
) throws {
47+
let directory = FileManager.default.temporaryDirectory
48+
.appendingPathComponent(UUID().uuidString, isDirectory: true)
49+
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
50+
defer { try? FileManager.default.removeItem(at: directory) }
51+
52+
let fileURL = directory.appendingPathComponent(name)
53+
#expect(FileManager.default.createFile(atPath: fileURL.path, contents: Data()))
54+
try body(fileURL)
55+
}
56+
}
57+
#endif

0 commit comments

Comments
 (0)