test fixes

This commit is contained in:
Peter Steinberger 2025-06-22 10:11:43 +02:00
parent 47eded4cb5
commit a791bbede8
4 changed files with 84 additions and 82 deletions

View file

@ -7,14 +7,14 @@ import Testing
@Suite("Server Manager Tests")
@MainActor
final class ServerManagerTests {
// We'll use the shared ServerManager instance since it's a singleton
/// We'll use the shared ServerManager instance since it's a singleton
let manager = ServerManager.shared
init() async {
// Ensure clean state before each test
await manager.stop()
}
deinit {
// Clean up is handled in init() of next test since we can't use async in deinit
}
@ -34,7 +34,7 @@ final class ServerManagerTests {
if let error = manager.lastError as? BunServerError {
#expect(error == .binaryNotFound)
}
// Server should not be running without the binary
#expect(!manager.isRunning)
#expect(manager.bunServer == nil)
@ -51,7 +51,7 @@ final class ServerManagerTests {
func startingAlreadyRunningServer() async throws {
// In test environment, we can't actually start the server
// So we'll test the logic of preventing duplicate starts
// First attempt to start
await manager.start()
try await Task.sleep(for: .milliseconds(100))
@ -64,7 +64,7 @@ final class ServerManagerTests {
// Should still have the same state (either nil or same instance)
#expect(manager.bunServer === firstServer)
// Error should be consistent
if let error1 = firstError as? BunServerError,
let error2 = manager.lastError as? BunServerError {
@ -77,7 +77,6 @@ final class ServerManagerTests {
@Test("Port configuration")
func portConfiguration() async throws {
// Store original port
let originalPort = manager.port
@ -99,7 +98,6 @@ final class ServerManagerTests {
DashboardAccessMode.network
])
func bindAddressConfiguration(mode: DashboardAccessMode) async throws {
// Store original mode
let originalMode = UserDefaults.standard.string(forKey: "dashboardAccessMode") ?? ""
@ -174,11 +172,11 @@ final class ServerManagerTests {
// Verify port configuration is maintained
#expect(manager.port == testPort)
// In test environment without binary, both instances should be nil
#expect(manager.bunServer == nil)
#expect(serverBeforeRestart == nil)
// Error should be consistent (binary not found)
if let error = manager.lastError as? BunServerError {
#expect(error == .binaryNotFound)
@ -228,7 +226,7 @@ final class ServerManagerTests {
// In test environment, server won't actually start
#expect(!manager.isRunning)
#expect(manager.bunServer == nil)
// Verify error is set appropriately
if let error = manager.lastError as? BunServerError {
#expect(error == .binaryNotFound)

View file

@ -128,9 +128,13 @@ struct SessionIdHandlingTests {
let started_at: String
let stdin: String
let streamOut: String
enum CodingKeys: String, CodingKey {
case cmdline, cwd, name, pid, status
case cmdline
case cwd
case name
case pid
case status
case started_at = "started_at"
case stdin
case streamOut = "stream-out"

View file

@ -8,70 +8,70 @@ import Testing
@MainActor
final class SessionMonitorTests {
let monitor = SessionMonitor.shared
init() async {
// Ensure clean state before each test
await monitor.refresh()
}
// MARK: - Basic Functionality Tests
@Test("Session count calculation")
func sessionCount() {
// When no sessions exist
#expect(monitor.sessionCount == 0)
// Note: Full integration tests would require a running server
// These tests verify the basic functionality of SessionMonitor
}
// MARK: - Cache Behavior Tests
@Test("Cache behavior", .tags(.performance))
func cacheBehavior() async {
// First call should fetch
_ = await monitor.getSessions()
// Immediate second call should use cache (no network request)
let cachedSessions = await monitor.getSessions()
// Verify we got a result (even if empty due to no server)
// cachedSessions is non-optional, so just verify it's a dictionary
#expect(cachedSessions.isEmpty || !cachedSessions.isEmpty)
}
@Test("Force refresh clears cache")
func forceRefresh() async {
// Get initial sessions
let initialSessions = await monitor.getSessions()
// Force refresh
await monitor.refresh()
// Next call should fetch fresh data
let refreshedSessions = await monitor.getSessions()
// Both should be dictionaries (possibly empty)
#expect(type(of: initialSessions) == type(of: refreshedSessions))
}
// MARK: - Error Handling Tests
@Test("Error handling", .tags(.reliability))
func errorHandling() async {
// When server is not running, should handle gracefully
_ = await monitor.getSessions()
// Should have empty sessions, not crash
#expect(monitor.sessions.isEmpty || !monitor.sessions.isEmpty)
// Last error might be nil (if treating connection errors as expected)
// or might contain error info
#expect(monitor.lastError == nil || monitor.lastError != nil)
}
// MARK: - Concurrent Access Tests
@Test("Concurrent session access", .tags(.concurrency))
func concurrentAccess() async {
await withTaskGroup(of: [String: ServerSessionInfo].self) { group in
@ -81,12 +81,12 @@ final class SessionMonitorTests {
await monitor.getSessions()
}
}
var results: [[String: ServerSessionInfo]] = []
for await result in group {
results.append(result)
}
// All concurrent calls should return consistent results
if let first = results.first {
for result in results {
@ -95,57 +95,57 @@ final class SessionMonitorTests {
}
}
}
// MARK: - Session Update Tests
@Test("Session updates are reflected")
func sessionUpdates() async {
// Get initial state
_ = monitor.sessionCount
// Refresh to get latest
await monitor.refresh()
// Count should be consistent with sessions dictionary
#expect(monitor.sessionCount == monitor.sessions.count)
#expect(monitor.sessionCount >= 0)
}
// MARK: - Integration Tests
@Test("Session monitor integration", .tags(.integration))
func integration() async {
// Test the full flow
await monitor.refresh()
let sessions = await monitor.getSessions()
// Verify session structure if we have any
for (sessionId, _) in sessions {
// Session ID should be valid
#expect(!sessionId.isEmpty)
// Note: ServerSessionInfo structure details would be validated here
// if we had access to the actual session info fields
}
}
// MARK: - Performance Tests
@Test("Cache performance", .tags(.performance))
func cachePerformance() async throws {
// Warm up cache
_ = await monitor.getSessions()
// Measure cached access time
let start = Date()
for _ in 0..<100 {
_ = await monitor.getSessions()
}
let elapsed = Date().timeIntervalSince(start)
// Cached access should be very fast
#expect(elapsed < 0.1, "Cached access took too long: \(elapsed)s for 100 calls")
}
}
}

View file

@ -1,6 +1,6 @@
import AppKit
import Foundation
import Testing
import AppKit
@testable import VibeTunnel
// MARK: - Terminal Launch Tests
@ -8,7 +8,7 @@ import AppKit
@Suite("Terminal Launch Tests")
struct TerminalLaunchTests {
// MARK: - URL Generation Tests
@Test("Terminal URL generation", arguments: [
(Terminal.iTerm2, "echo 'Hello World'", "iterm2://run?command=echo%20\'Hello%20World\'"),
(Terminal.iTerm2, "cd /tmp && ls", "iterm2://run?command=cd%20/tmp%20%26%26%20ls"),
@ -24,33 +24,33 @@ struct TerminalLaunchTests {
#expect(expectedURL == nil)
}
}
// MARK: - Command Arguments Tests
@Test("Command argument generation for terminals")
func commandArgumentGeneration() {
let command = "echo 'Hello World'"
// Test Alacritty arguments
let alacrittyArgs = Terminal.alacritty.commandArguments(for: command)
#expect(alacrittyArgs == ["-e", "/bin/bash", "-c", command])
// Test WezTerm arguments
let weztermArgs = Terminal.wezterm.commandArguments(for: command)
#expect(weztermArgs == ["start", "--", "/bin/bash", "-c", command])
// Test Terminal.app (limited support)
let terminalArgs = Terminal.terminal.commandArguments(for: command)
#expect(terminalArgs == [])
}
// MARK: - Working Directory Tests
@Test("Working directory support")
func workingDirectorySupport() {
let workDir = "/Users/test/projects"
let command = "ls -la"
// Alacritty with working directory
let alacrittyArgs = Terminal.alacritty.commandArguments(
for: command,
@ -60,7 +60,7 @@ struct TerminalLaunchTests {
"--working-directory", workDir,
"-e", "/bin/bash", "-c", command
])
// WezTerm with working directory
let weztermArgs = Terminal.wezterm.commandArguments(
for: command,
@ -70,7 +70,7 @@ struct TerminalLaunchTests {
"start", "--cwd", workDir,
"--", "/bin/bash", "-c", command
])
// iTerm2 URL with working directory
if let url = Terminal.iTerm2.commandURL(for: command, workingDirectory: workDir) {
#expect(url.absoluteString.contains("cd="))
@ -79,62 +79,62 @@ struct TerminalLaunchTests {
)
}
}
// MARK: - Complex Command Tests
@Test("Complex command encoding")
func complexCommandEncoding() {
let complexCommand = "git log --oneline -10 && echo 'Done!'"
// Test iTerm2 URL encoding
if let url = Terminal.iTerm2.commandURL(for: complexCommand) {
// URLComponents encodes differently, so just check the URL contains the command
#expect(url.absoluteString.contains("command="))
#expect(url.absoluteString.contains("git"))
}
// Test argument generation doesn't break the command
let alacrittyArgs = Terminal.alacritty.commandArguments(for: complexCommand)
#expect(alacrittyArgs.last == complexCommand)
}
// MARK: - Terminal Detection Tests
@Test("Terminal detection")
func terminalDetection() {
// At least Terminal.app should be available on macOS
#expect(Terminal.installed.contains(.terminal))
// Check that installed terminals have valid paths
for terminal in Terminal.installed {
// Check if terminal is installed
#expect(NSWorkspace.shared.urlForApplication(withBundleIdentifier: terminal.bundleIdentifier) != nil)
}
}
// MARK: - Environment Variable Tests
@Test("Launching with environment variables")
@MainActor
func environmentVariables() {
_ = ["MY_VAR": "test_value", "PATH": "/custom/path:/usr/bin"]
_ = "echo $MY_VAR"
// Test that environment variables can be passed
_ = TerminalLauncher.shared
// This would need to be implemented in TerminalLauncher
// Just testing the concept here
#expect(Bool(true)) // No-throw test
}
// MARK: - Script File Tests
@Test("Script file execution")
func scriptFileExecution() throws {
let tempDir = FileManager.default.temporaryDirectory
let scriptPath = tempDir.appendingPathComponent("test_script.sh")
// Create a test script
let scriptContent = """
#!/bin/bash
@ -142,16 +142,16 @@ struct TerminalLaunchTests {
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
#expect(FileManager.default.fileExists(atPath: scriptPath.path))
// Cleanup
try? FileManager.default.removeItem(at: scriptPath)
}
@ -171,7 +171,7 @@ extension Terminal {
}
args += ["-e", "/bin/bash", "-c", command]
return args
case .wezterm:
var args = ["start"]
if let workDir = workingDirectory {
@ -179,12 +179,12 @@ extension Terminal {
}
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 {
@ -198,9 +198,9 @@ extension Terminal {
}
components?.queryItems = queryItems
return components?.url
default:
return nil
}
}
}
}