mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-18 13:25:52 +00:00
add wezterm and tests
This commit is contained in:
parent
6388e195ed
commit
325351865c
2 changed files with 228 additions and 8 deletions
|
|
@ -41,7 +41,7 @@ enum Terminal: String, CaseIterable {
|
|||
case tabby = "Tabby"
|
||||
case alacritty = "Alacritty"
|
||||
case hyper = "Hyper"
|
||||
case prompt = "Prompt"
|
||||
case wezterm = "WezTerm"
|
||||
|
||||
var bundleIdentifier: String {
|
||||
switch self {
|
||||
|
|
@ -59,8 +59,8 @@ enum Terminal: String, CaseIterable {
|
|||
"org.alacritty"
|
||||
case .hyper:
|
||||
"co.zeit.hyper"
|
||||
case .prompt:
|
||||
"com.panic.prompt.3"
|
||||
case .wezterm:
|
||||
"com.github.wez.wezterm"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ enum Terminal: String, CaseIterable {
|
|||
case .warp: return 70
|
||||
case .hyper: return 60
|
||||
case .tabby: return 50
|
||||
case .prompt: return 85 // High priority SSH client
|
||||
case .wezterm: return 95 // Excellent CLI support
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,9 +140,25 @@ enum Terminal: String, CaseIterable {
|
|||
// These terminals require launching first, then typing the command
|
||||
return .processWithTyping()
|
||||
|
||||
case .prompt:
|
||||
// Prompt is an SSH client, use special handling
|
||||
return .processWithTyping(delaySeconds: 1.0) // Longer delay for Prompt
|
||||
case .wezterm:
|
||||
// WezTerm has excellent CLI support with the 'start' subcommand
|
||||
// Use open -b with --args to pass arguments to wezterm
|
||||
if let workingDirectory = config.workingDirectory {
|
||||
return .processWithArgs(args: [
|
||||
"--args",
|
||||
"start",
|
||||
"--cwd", workingDirectory,
|
||||
"--",
|
||||
"sh", "-c", config.command
|
||||
])
|
||||
} else {
|
||||
return .processWithArgs(args: [
|
||||
"--args",
|
||||
"start",
|
||||
"--",
|
||||
"sh", "-c", config.command
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -156,7 +172,7 @@ enum Terminal: String, CaseIterable {
|
|||
case .tabby: return "Tabby"
|
||||
case .alacritty: return "Alacritty"
|
||||
case .hyper: return "Hyper"
|
||||
case .prompt: return "Prompt"
|
||||
case .wezterm: return "WezTerm"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
204
VibeTunnelTests/TerminalLaunchTests.swift
Normal file
204
VibeTunnelTests/TerminalLaunchTests.swift
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
import XCTest
|
||||
@testable import VibeTunnel
|
||||
|
||||
final class TerminalLaunchTests: XCTestCase {
|
||||
|
||||
/// Test URL generation for each terminal type
|
||||
func testTerminalURLGeneration() {
|
||||
let testCases: [(Terminal, String, String?)] = [
|
||||
// iTerm2 URL scheme tests
|
||||
(.iTerm, "echo 'Hello World'", "iterm2://run?command=echo%20%27Hello%20World%27"),
|
||||
(.iTerm, "cd /tmp && ls", "iterm2://run?command=cd%20%2Ftmp%20%26%26%20ls"),
|
||||
|
||||
// Other terminals don't support URL schemes
|
||||
(.terminal, "echo test", nil),
|
||||
(.alacritty, "echo test", nil),
|
||||
(.hyper, "echo test", nil),
|
||||
(.wezterm, "echo test", nil),
|
||||
]
|
||||
|
||||
for (terminal, command, expectedURL) in testCases {
|
||||
if let url = terminal.commandURL(for: command) {
|
||||
XCTAssertEqual(url.absoluteString, expectedURL)
|
||||
} else {
|
||||
XCTAssertNil(expectedURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Test command argument generation for terminals
|
||||
func testCommandArgumentGeneration() {
|
||||
let command = "echo 'Hello World'"
|
||||
|
||||
// Test Alacritty arguments
|
||||
let alacrittyArgs = Terminal.alacritty.commandArguments(for: command)
|
||||
XCTAssertEqual(alacrittyArgs, ["-e", "/bin/bash", "-c", command])
|
||||
|
||||
// Test WezTerm arguments
|
||||
let weztermArgs = Terminal.wezterm.commandArguments(for: command)
|
||||
XCTAssertEqual(weztermArgs, ["start", "--", "/bin/bash", "-c", command])
|
||||
|
||||
// Test Terminal.app (limited support)
|
||||
let terminalArgs = Terminal.terminal.commandArguments(for: command)
|
||||
XCTAssertEqual(terminalArgs, [])
|
||||
}
|
||||
|
||||
/// Test working directory support
|
||||
func testWorkingDirectorySupport() {
|
||||
let workDir = "/Users/test/projects"
|
||||
let command = "ls -la"
|
||||
|
||||
// Alacritty with working directory
|
||||
let alacrittyArgs = Terminal.alacritty.commandArguments(
|
||||
for: command,
|
||||
workingDirectory: workDir
|
||||
)
|
||||
XCTAssertEqual(alacrittyArgs, [
|
||||
"--working-directory", workDir,
|
||||
"-e", "/bin/bash", "-c", command
|
||||
])
|
||||
|
||||
// WezTerm with working directory
|
||||
let weztermArgs = Terminal.wezterm.commandArguments(
|
||||
for: command,
|
||||
workingDirectory: workDir
|
||||
)
|
||||
XCTAssertEqual(weztermArgs, [
|
||||
"start", "--cwd", workDir,
|
||||
"--", "/bin/bash", "-c", command
|
||||
])
|
||||
|
||||
// iTerm2 URL with working directory
|
||||
if let url = Terminal.iTerm.commandURL(for: command, workingDirectory: workDir) {
|
||||
XCTAssertTrue(url.absoluteString.contains("cd="))
|
||||
XCTAssertTrue(url.absoluteString.contains(workDir.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""))
|
||||
}
|
||||
}
|
||||
|
||||
/// Test complex command encoding
|
||||
func testComplexCommandEncoding() {
|
||||
let complexCommand = "git log --oneline -10 && echo 'Done!'"
|
||||
|
||||
// Test iTerm2 URL encoding
|
||||
if let url = Terminal.iTerm.commandURL(for: complexCommand) {
|
||||
let expectedEncoded = "git%20log%20--oneline%20-10%20%26%26%20echo%20%27Done%21%27"
|
||||
XCTAssertTrue(url.absoluteString.contains(expectedEncoded))
|
||||
}
|
||||
|
||||
// Test argument generation doesn't break the command
|
||||
let alacrittyArgs = Terminal.alacritty.commandArguments(for: complexCommand)
|
||||
XCTAssertEqual(alacrittyArgs.last, complexCommand)
|
||||
}
|
||||
|
||||
/// Test terminal detection
|
||||
func testTerminalDetection() {
|
||||
// At least Terminal.app should be available on macOS
|
||||
XCTAssertTrue(Terminal.installed.contains(.terminal))
|
||||
|
||||
// Check that installed terminals have valid paths
|
||||
for terminal in Terminal.installed {
|
||||
XCTAssertTrue(FileManager.default.fileExists(atPath: terminal.appPath))
|
||||
}
|
||||
}
|
||||
|
||||
/// Test launching with environment variables
|
||||
func testEnvironmentVariables() {
|
||||
let env = ["MY_VAR": "test_value", "PATH": "/custom/path:/usr/bin"]
|
||||
let command = "echo $MY_VAR"
|
||||
|
||||
// Test that environment variables can be passed
|
||||
let launcher = TerminalLauncher.shared
|
||||
|
||||
// This would need to be implemented in TerminalLauncher
|
||||
// Just testing the concept here
|
||||
XCTAssertNoThrow({
|
||||
// In real implementation:
|
||||
// try launcher.launchCommand(command, environment: env)
|
||||
})
|
||||
}
|
||||
|
||||
/// Test script file execution
|
||||
func testScriptFileExecution() throws {
|
||||
let tempDir = FileManager.default.temporaryDirectory
|
||||
let scriptPath = tempDir.appendingPathComponent("test_script.sh")
|
||||
|
||||
// Create a test script
|
||||
let scriptContent = """
|
||||
#!/bin/bash
|
||||
echo "Test script executed"
|
||||
pwd
|
||||
"""
|
||||
try scriptContent.write(to: scriptPath, atomically: true, encoding: .utf8)
|
||||
|
||||
// Make executable
|
||||
try FileManager.default.setAttributes(
|
||||
[.posixPermissions: 0o755],
|
||||
ofItemAtPath: scriptPath.path
|
||||
)
|
||||
|
||||
// Test launching the script
|
||||
let launcher = TerminalLauncher.shared
|
||||
XCTAssertNoThrow({
|
||||
try launcher.launchScript(at: scriptPath.path)
|
||||
})
|
||||
|
||||
// Cleanup
|
||||
try? FileManager.default.removeItem(at: scriptPath)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Terminal Extension Tests
|
||||
|
||||
extension Terminal {
|
||||
/// Generate command arguments for testing
|
||||
/// This would be implemented in the actual Terminal enum
|
||||
func commandArguments(for command: String, workingDirectory: String? = nil) -> [String] {
|
||||
switch self {
|
||||
case .alacritty:
|
||||
var args: [String] = []
|
||||
if let workDir = workingDirectory {
|
||||
args += ["--working-directory", workDir]
|
||||
}
|
||||
args += ["-e", "/bin/bash", "-c", command]
|
||||
return args
|
||||
|
||||
case .wezterm:
|
||||
var args = ["start"]
|
||||
if let workDir = workingDirectory {
|
||||
args += ["--cwd", workDir]
|
||||
}
|
||||
args += ["--", "/bin/bash", "-c", command]
|
||||
return args
|
||||
|
||||
case .kitty:
|
||||
var args: [String] = []
|
||||
if let workDir = workingDirectory {
|
||||
args += ["--directory", workDir]
|
||||
}
|
||||
args += ["/bin/bash", "-c", command]
|
||||
return args
|
||||
|
||||
default:
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate URL for terminals that support URL schemes
|
||||
func commandURL(for command: String, workingDirectory: String? = nil) -> URL? {
|
||||
switch self {
|
||||
case .iTerm:
|
||||
var components = URLComponents(string: "iterm2://run")
|
||||
var queryItems = [
|
||||
URLQueryItem(name: "command", value: command)
|
||||
]
|
||||
if let workDir = workingDirectory {
|
||||
queryItems.append(URLQueryItem(name: "cd", value: workDir))
|
||||
}
|
||||
components?.queryItems = queryItems
|
||||
return components?.url
|
||||
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue