mirror of
https://github.com/samsonjs/Peekaboo.git
synced 2026-04-22 14:05:58 +00:00
Apply SwiftFormat to new test files
- Fix import ordering (XCTest after module imports) - Add missing newlines at end of files - Fix number formatting (underscore separators) - Apply consistent formatting to switch statements
This commit is contained in:
parent
f4a41f8355
commit
8894154be6
5 changed files with 185 additions and 187 deletions
|
|
@ -1,46 +1,46 @@
|
|||
import XCTest
|
||||
@testable import peekaboo
|
||||
import XCTest
|
||||
|
||||
final class ApplicationFinderTests: XCTestCase {
|
||||
var applicationFinder: ApplicationFinder!
|
||||
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
applicationFinder = ApplicationFinder()
|
||||
}
|
||||
|
||||
|
||||
override func tearDown() {
|
||||
applicationFinder = nil
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
|
||||
// MARK: - findRunningApplication Tests
|
||||
|
||||
|
||||
func testFindRunningApplicationExactMatch() throws {
|
||||
// Test finding an app that should always be running on macOS
|
||||
let result = try applicationFinder.findRunningApplication(named: "Finder")
|
||||
|
||||
|
||||
XCTAssertNotNil(result)
|
||||
XCTAssertEqual(result?.localizedName, "Finder")
|
||||
XCTAssertEqual(result?.bundleIdentifier, "com.apple.finder")
|
||||
}
|
||||
|
||||
|
||||
func testFindRunningApplicationCaseInsensitive() throws {
|
||||
// Test case-insensitive matching
|
||||
let result = try applicationFinder.findRunningApplication(named: "finder")
|
||||
|
||||
|
||||
XCTAssertNotNil(result)
|
||||
XCTAssertEqual(result?.localizedName, "Finder")
|
||||
}
|
||||
|
||||
|
||||
func testFindRunningApplicationByBundleIdentifier() throws {
|
||||
// Test finding by bundle identifier
|
||||
let result = try applicationFinder.findRunningApplication(named: "com.apple.finder")
|
||||
|
||||
|
||||
XCTAssertNotNil(result)
|
||||
XCTAssertEqual(result?.bundleIdentifier, "com.apple.finder")
|
||||
}
|
||||
|
||||
|
||||
func testFindRunningApplicationNotFound() {
|
||||
// Test app not found error
|
||||
XCTAssertThrowsError(try applicationFinder.findRunningApplication(named: "NonExistentApp12345")) { error in
|
||||
|
|
@ -51,52 +51,52 @@ final class ApplicationFinderTests: XCTestCase {
|
|||
XCTAssertEqual(captureError, .appNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testFindRunningApplicationPartialMatch() throws {
|
||||
// Test partial name matching
|
||||
let result = try applicationFinder.findRunningApplication(named: "Find")
|
||||
|
||||
|
||||
// Should find Finder as closest match
|
||||
XCTAssertNotNil(result)
|
||||
XCTAssertEqual(result?.localizedName, "Finder")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Fuzzy Matching Tests
|
||||
|
||||
|
||||
func testFuzzyMatchingScore() {
|
||||
// Test the fuzzy matching algorithm
|
||||
let finder = "Finder"
|
||||
|
||||
|
||||
// Exact match should have highest score
|
||||
XCTAssertEqual(applicationFinder.fuzzyMatch("Finder", with: finder), 1.0)
|
||||
|
||||
|
||||
// Case differences should still score high
|
||||
XCTAssertGreaterThan(applicationFinder.fuzzyMatch("finder", with: finder), 0.8)
|
||||
|
||||
|
||||
// Partial matches should score lower but still match
|
||||
XCTAssertGreaterThan(applicationFinder.fuzzyMatch("Find", with: finder), 0.5)
|
||||
XCTAssertLessThan(applicationFinder.fuzzyMatch("Find", with: finder), 0.9)
|
||||
|
||||
|
||||
// Completely different should score very low
|
||||
XCTAssertLessThan(applicationFinder.fuzzyMatch("Safari", with: finder), 0.3)
|
||||
}
|
||||
|
||||
|
||||
func testFuzzyMatchingWithSpaces() {
|
||||
// Test matching with spaces and special characters
|
||||
let appName = "Google Chrome"
|
||||
|
||||
|
||||
// Various ways users might type Chrome
|
||||
XCTAssertGreaterThan(applicationFinder.fuzzyMatch("chrome", with: appName), 0.5)
|
||||
XCTAssertGreaterThan(applicationFinder.fuzzyMatch("google", with: appName), 0.5)
|
||||
XCTAssertGreaterThan(applicationFinder.fuzzyMatch("googlechrome", with: appName), 0.7)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Performance Tests
|
||||
|
||||
|
||||
func testFindApplicationPerformance() throws {
|
||||
// Test that finding an app completes in reasonable time
|
||||
measure {
|
||||
_ = try? applicationFinder.findRunningApplication(named: "Finder")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
import XCTest
|
||||
import ArgumentParser
|
||||
@testable import peekaboo
|
||||
import XCTest
|
||||
|
||||
final class ImageCommandTests: XCTestCase {
|
||||
|
||||
// MARK: - Command Parsing Tests
|
||||
|
||||
|
||||
func testImageCommandParsing() throws {
|
||||
// Test basic command parsing
|
||||
let command = try ImageCommand.parse([])
|
||||
|
||||
|
||||
// Verify defaults
|
||||
XCTAssertEqual(command.mode, .activeWindow)
|
||||
XCTAssertEqual(command.format, .png)
|
||||
|
|
@ -19,66 +18,66 @@ final class ImageCommandTests: XCTestCase {
|
|||
XCTAssertFalse(command.includeWindowFrame)
|
||||
XCTAssertEqual(command.quality, 90)
|
||||
}
|
||||
|
||||
|
||||
func testImageCommandWithScreenMode() throws {
|
||||
// Test screen capture mode
|
||||
let command = try ImageCommand.parse(["--mode", "screen"])
|
||||
|
||||
|
||||
XCTAssertEqual(command.mode, .screen)
|
||||
}
|
||||
|
||||
|
||||
func testImageCommandWithAppSpecifier() throws {
|
||||
// Test app-specific capture
|
||||
let command = try ImageCommand.parse([
|
||||
"--mode", "app",
|
||||
"--app", "Finder"
|
||||
])
|
||||
|
||||
|
||||
XCTAssertEqual(command.mode, .app)
|
||||
XCTAssertEqual(command.app, "Finder")
|
||||
}
|
||||
|
||||
|
||||
func testImageCommandWithWindowId() throws {
|
||||
// Test window ID capture
|
||||
let command = try ImageCommand.parse([
|
||||
"--mode", "window",
|
||||
"--window-id", "123"
|
||||
])
|
||||
|
||||
|
||||
XCTAssertEqual(command.mode, .window)
|
||||
XCTAssertEqual(command.windowId, 123)
|
||||
}
|
||||
|
||||
|
||||
func testImageCommandWithOutput() throws {
|
||||
// Test output path specification
|
||||
let outputPath = "/tmp/test-image.png"
|
||||
let command = try ImageCommand.parse([
|
||||
"--output", outputPath
|
||||
])
|
||||
|
||||
|
||||
XCTAssertEqual(command.output, outputPath)
|
||||
}
|
||||
|
||||
|
||||
func testImageCommandWithFormat() throws {
|
||||
// Test JPEG format
|
||||
let command = try ImageCommand.parse([
|
||||
"--format", "jpg",
|
||||
"--quality", "85"
|
||||
])
|
||||
|
||||
|
||||
XCTAssertEqual(command.format, .jpg)
|
||||
XCTAssertEqual(command.quality, 85)
|
||||
}
|
||||
|
||||
|
||||
func testImageCommandWithJSONOutput() throws {
|
||||
// Test JSON output flag
|
||||
let command = try ImageCommand.parse(["--json-output"])
|
||||
|
||||
|
||||
XCTAssertTrue(command.jsonOutput)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Validation Tests
|
||||
|
||||
|
||||
func testImageCommandValidationMissingApp() {
|
||||
// Test that app mode requires app name
|
||||
XCTAssertThrowsError(try ImageCommand.parse([
|
||||
|
|
@ -86,7 +85,7 @@ final class ImageCommandTests: XCTestCase {
|
|||
// Missing --app parameter
|
||||
]))
|
||||
}
|
||||
|
||||
|
||||
func testImageCommandValidationMissingWindowId() {
|
||||
// Test that window mode requires window ID
|
||||
XCTAssertThrowsError(try ImageCommand.parse([
|
||||
|
|
@ -94,20 +93,20 @@ final class ImageCommandTests: XCTestCase {
|
|||
// Missing --window-id parameter
|
||||
]))
|
||||
}
|
||||
|
||||
|
||||
func testImageCommandValidationInvalidQuality() {
|
||||
// Test quality validation
|
||||
XCTAssertThrowsError(try ImageCommand.parse([
|
||||
"--quality", "150" // > 100
|
||||
]))
|
||||
|
||||
|
||||
XCTAssertThrowsError(try ImageCommand.parse([
|
||||
"--quality", "-10" // < 0
|
||||
]))
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Capture Mode Tests
|
||||
|
||||
|
||||
func testCaptureModeRawValues() {
|
||||
// Test capture mode string values
|
||||
XCTAssertEqual(CaptureMode.screen.rawValue, "screen")
|
||||
|
|
@ -116,65 +115,65 @@ final class ImageCommandTests: XCTestCase {
|
|||
XCTAssertEqual(CaptureMode.window.rawValue, "window")
|
||||
XCTAssertEqual(CaptureMode.area.rawValue, "area")
|
||||
}
|
||||
|
||||
|
||||
func testImageFormatRawValues() {
|
||||
// Test image format values
|
||||
XCTAssertEqual(ImageFormat.png.rawValue, "png")
|
||||
XCTAssertEqual(ImageFormat.jpg.rawValue, "jpg")
|
||||
XCTAssertEqual(ImageFormat.data.rawValue, "data")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Helper Method Tests
|
||||
|
||||
|
||||
func testGenerateFilename() {
|
||||
// Test filename generation with pattern
|
||||
let pattern = "{app}_{mode}_{timestamp}"
|
||||
let date = Date(timeIntervalSince1970: 1700000000) // Fixed date for testing
|
||||
|
||||
let date = Date(timeIntervalSince1970: 1_700_000_000) // Fixed date for testing
|
||||
|
||||
// Mock the filename generation logic
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateFormat = "yyyy-MM-dd_HH-mm-ss"
|
||||
let timestamp = formatter.string(from: date)
|
||||
|
||||
|
||||
let filename = pattern
|
||||
.replacingOccurrences(of: "{app}", with: "Finder")
|
||||
.replacingOccurrences(of: "{mode}", with: "window")
|
||||
.replacingOccurrences(of: "{timestamp}", with: timestamp)
|
||||
|
||||
|
||||
XCTAssertTrue(filename.contains("Finder"))
|
||||
XCTAssertTrue(filename.contains("window"))
|
||||
XCTAssertTrue(filename.contains("2023-11-14")) // Date from timestamp
|
||||
}
|
||||
|
||||
|
||||
func testBlurDetection() {
|
||||
// Test blur detection threshold logic
|
||||
let blurThresholds: [Double] = [0.0, 0.5, 1.0]
|
||||
|
||||
|
||||
for threshold in blurThresholds {
|
||||
XCTAssertGreaterThanOrEqual(threshold, 0.0)
|
||||
XCTAssertLessThanOrEqual(threshold, 1.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Error Response Tests
|
||||
|
||||
|
||||
func testErrorResponseCreation() throws {
|
||||
// Test error response structure
|
||||
let error = CaptureError.appNotFound
|
||||
|
||||
|
||||
let errorData = SwiftCliErrorData(
|
||||
error: error.rawValue,
|
||||
message: error.description,
|
||||
details: nil,
|
||||
suggestions: []
|
||||
)
|
||||
|
||||
|
||||
XCTAssertEqual(errorData.error, "APP_NOT_FOUND")
|
||||
XCTAssertEqual(errorData.message, "Application not found")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Integration Tests
|
||||
|
||||
|
||||
func testImageCaptureDataEncoding() throws {
|
||||
// Test that ImageCaptureData can be encoded to JSON
|
||||
let captureData = ImageCaptureData(
|
||||
|
|
@ -184,7 +183,7 @@ final class ImageCommandTests: XCTestCase {
|
|||
metadata: ImageMetadata(
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
fileSize: 1024000,
|
||||
fileSize: 1_024_000,
|
||||
format: "png",
|
||||
colorSpace: "sRGB",
|
||||
bitsPerPixel: 24,
|
||||
|
|
@ -197,20 +196,20 @@ final class ImageCommandTests: XCTestCase {
|
|||
blurScore: 0.1,
|
||||
debugLogs: []
|
||||
)
|
||||
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||
|
||||
|
||||
let data = try encoder.encode(captureData)
|
||||
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
|
||||
|
||||
|
||||
XCTAssertNotNil(json)
|
||||
XCTAssertEqual(json?["image_data"] as? String, "base64data")
|
||||
XCTAssertEqual(json?["capture_mode"] as? String, "screen")
|
||||
XCTAssertEqual(json?["is_blurry"] as? Bool, false)
|
||||
|
||||
|
||||
let metadata = json?["metadata"] as? [String: Any]
|
||||
XCTAssertEqual(metadata?["width"] as? Int, 1920)
|
||||
XCTAssertEqual(metadata?["height"] as? Int, 1080)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,26 @@
|
|||
import XCTest
|
||||
import ArgumentParser
|
||||
@testable import peekaboo
|
||||
import XCTest
|
||||
|
||||
final class ListCommandTests: XCTestCase {
|
||||
|
||||
// MARK: - Command Parsing Tests
|
||||
|
||||
|
||||
func testListCommandParsing() throws {
|
||||
// Test basic command parsing
|
||||
let command = try ListCommand.parse(["running_applications"])
|
||||
|
||||
|
||||
XCTAssertEqual(command.type, .runningApplications)
|
||||
XCTAssertFalse(command.jsonOutput)
|
||||
}
|
||||
|
||||
|
||||
func testListCommandWithJSONOutput() throws {
|
||||
// Test JSON output flag
|
||||
let command = try ListCommand.parse(["server_status", "--json-output"])
|
||||
|
||||
|
||||
XCTAssertEqual(command.type, .serverStatus)
|
||||
XCTAssertTrue(command.jsonOutput)
|
||||
}
|
||||
|
||||
|
||||
func testListCommandAllTypes() throws {
|
||||
// Test all list types parse correctly
|
||||
let types: [(String, ListType)] = [
|
||||
|
|
@ -29,53 +28,53 @@ final class ListCommandTests: XCTestCase {
|
|||
("windows", .windows),
|
||||
("server_status", .serverStatus)
|
||||
]
|
||||
|
||||
|
||||
for (arg, expectedType) in types {
|
||||
let command = try ListCommand.parse([arg])
|
||||
XCTAssertEqual(command.type, expectedType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testListCommandWithApp() throws {
|
||||
// Test windows list with app filter
|
||||
let command = try ListCommand.parse([
|
||||
"windows",
|
||||
"--app", "Finder"
|
||||
])
|
||||
|
||||
|
||||
XCTAssertEqual(command.type, .windows)
|
||||
XCTAssertEqual(command.app, "Finder")
|
||||
}
|
||||
|
||||
|
||||
func testListCommandWithWindowDetail() throws {
|
||||
// Test window detail options
|
||||
let command = try ListCommand.parse([
|
||||
"windows",
|
||||
"--window-detail", "full"
|
||||
])
|
||||
|
||||
|
||||
XCTAssertEqual(command.type, .windows)
|
||||
XCTAssertEqual(command.windowDetail, .full)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ListType Tests
|
||||
|
||||
|
||||
func testListTypeRawValues() {
|
||||
// Test list type string values
|
||||
XCTAssertEqual(ListType.runningApplications.rawValue, "running_applications")
|
||||
XCTAssertEqual(ListType.windows.rawValue, "windows")
|
||||
XCTAssertEqual(ListType.serverStatus.rawValue, "server_status")
|
||||
}
|
||||
|
||||
|
||||
func testWindowDetailOptionRawValues() {
|
||||
// Test window detail option values
|
||||
XCTAssertEqual(WindowDetailOption.none.rawValue, "none")
|
||||
XCTAssertEqual(WindowDetailOption.basic.rawValue, "basic")
|
||||
XCTAssertEqual(WindowDetailOption.full.rawValue, "full")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Data Structure Tests
|
||||
|
||||
|
||||
func testApplicationListDataEncoding() throws {
|
||||
// Test ApplicationListData JSON encoding
|
||||
let appData = ApplicationListData(
|
||||
|
|
@ -94,24 +93,24 @@ final class ListCommandTests: XCTestCase {
|
|||
)
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||
|
||||
|
||||
let data = try encoder.encode(appData)
|
||||
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
|
||||
|
||||
|
||||
XCTAssertNotNil(json)
|
||||
let apps = json?["applications"] as? [[String: Any]]
|
||||
XCTAssertEqual(apps?.count, 2)
|
||||
|
||||
|
||||
let firstApp = apps?.first
|
||||
XCTAssertEqual(firstApp?["name"] as? String, "Finder")
|
||||
XCTAssertEqual(firstApp?["bundle_identifier"] as? String, "com.apple.finder")
|
||||
XCTAssertEqual(firstApp?["process_identifier"] as? Int, 123)
|
||||
XCTAssertEqual(firstApp?["is_active"] as? Bool, true)
|
||||
}
|
||||
|
||||
|
||||
func testWindowListDataEncoding() throws {
|
||||
// Test WindowListData JSON encoding
|
||||
let windowData = WindowListData(
|
||||
|
|
@ -135,76 +134,76 @@ final class ListCommandTests: XCTestCase {
|
|||
)
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||
|
||||
|
||||
let data = try encoder.encode(windowData)
|
||||
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
|
||||
|
||||
|
||||
XCTAssertNotNil(json)
|
||||
|
||||
|
||||
let targetApp = json?["target_app"] as? [String: Any]
|
||||
XCTAssertEqual(targetApp?["name"] as? String, "Finder")
|
||||
|
||||
|
||||
let windows = json?["windows"] as? [[String: Any]]
|
||||
XCTAssertEqual(windows?.count, 1)
|
||||
|
||||
|
||||
let firstWindow = windows?.first
|
||||
let windowInfo = firstWindow?["window_info"] as? [String: Any]
|
||||
XCTAssertEqual(windowInfo?["window_id"] as? Int, 1001)
|
||||
XCTAssertEqual(windowInfo?["owning_application"] as? String, "Finder")
|
||||
XCTAssertEqual(windowInfo?["window_title"] as? String, "Documents")
|
||||
}
|
||||
|
||||
|
||||
func testServerStatusEncoding() throws {
|
||||
// Test ServerStatus JSON encoding
|
||||
let status = ServerStatus(
|
||||
hasScreenRecordingPermission: true,
|
||||
hasAccessibilityPermission: false
|
||||
)
|
||||
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||
|
||||
|
||||
let data = try encoder.encode(status)
|
||||
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
|
||||
|
||||
|
||||
XCTAssertNotNil(json)
|
||||
XCTAssertEqual(json?["has_screen_recording_permission"] as? Bool, true)
|
||||
XCTAssertEqual(json?["has_accessibility_permission"] as? Bool, false)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Window Specifier Tests
|
||||
|
||||
|
||||
func testWindowSpecifierFromApp() {
|
||||
// Test window specifier creation from app
|
||||
let specifier = WindowSpecifier.app("Finder")
|
||||
|
||||
|
||||
switch specifier {
|
||||
case .app(let name):
|
||||
case let .app(name):
|
||||
XCTAssertEqual(name, "Finder")
|
||||
default:
|
||||
XCTFail("Expected app specifier")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testWindowSpecifierFromWindowId() {
|
||||
// Test window specifier creation from window ID
|
||||
let specifier = WindowSpecifier.windowId(123)
|
||||
|
||||
|
||||
switch specifier {
|
||||
case .windowId(let id):
|
||||
case let .windowId(id):
|
||||
XCTAssertEqual(id, 123)
|
||||
default:
|
||||
XCTFail("Expected windowId specifier")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testWindowSpecifierActiveWindow() {
|
||||
// Test active window specifier
|
||||
let specifier = WindowSpecifier.activeWindow
|
||||
|
||||
|
||||
switch specifier {
|
||||
case .activeWindow:
|
||||
// Success
|
||||
|
|
@ -213,21 +212,21 @@ final class ListCommandTests: XCTestCase {
|
|||
XCTFail("Expected activeWindow specifier")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Error Handling Tests
|
||||
|
||||
|
||||
func testListCommandInvalidType() {
|
||||
// Test invalid list type
|
||||
XCTAssertThrowsError(try ListCommand.parse(["invalid_type"]))
|
||||
}
|
||||
|
||||
|
||||
func testListCommandMissingType() {
|
||||
// Test missing list type
|
||||
XCTAssertThrowsError(try ListCommand.parse([]))
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Performance Tests
|
||||
|
||||
|
||||
func testApplicationInfoEncodingPerformance() throws {
|
||||
// Test performance of encoding many applications
|
||||
let apps = (0..<100).map { i in
|
||||
|
|
@ -238,13 +237,13 @@ final class ListCommandTests: XCTestCase {
|
|||
isActive: i == 0
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
let appData = ApplicationListData(applications: apps)
|
||||
let encoder = JSONEncoder()
|
||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||
|
||||
|
||||
measure {
|
||||
_ = try? encoder.encode(appData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,123 +1,123 @@
|
|||
import XCTest
|
||||
@testable import peekaboo
|
||||
import XCTest
|
||||
|
||||
final class PermissionsCheckerTests: XCTestCase {
|
||||
var permissionsChecker: PermissionsChecker!
|
||||
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
permissionsChecker = PermissionsChecker()
|
||||
}
|
||||
|
||||
|
||||
override func tearDown() {
|
||||
permissionsChecker = nil
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
|
||||
// MARK: - hasScreenRecordingPermission Tests
|
||||
|
||||
|
||||
func testHasScreenRecordingPermission() {
|
||||
// Test screen recording permission check
|
||||
let hasPermission = permissionsChecker.hasScreenRecordingPermission()
|
||||
|
||||
|
||||
// This test will pass or fail based on actual system permissions
|
||||
// In CI/CD, this might need to be mocked
|
||||
XCTAssertNotNil(hasPermission)
|
||||
|
||||
|
||||
// If running in a test environment without permissions, we expect false
|
||||
// If running locally with permissions granted, we expect true
|
||||
print("Screen recording permission status: \(hasPermission)")
|
||||
}
|
||||
|
||||
|
||||
func testScreenRecordingPermissionConsistency() {
|
||||
// Test that multiple calls return consistent results
|
||||
let firstCheck = permissionsChecker.hasScreenRecordingPermission()
|
||||
let secondCheck = permissionsChecker.hasScreenRecordingPermission()
|
||||
|
||||
|
||||
XCTAssertEqual(firstCheck, secondCheck, "Permission check should be consistent")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - hasAccessibilityPermission Tests
|
||||
|
||||
|
||||
func testHasAccessibilityPermission() {
|
||||
// Test accessibility permission check
|
||||
let hasPermission = permissionsChecker.hasAccessibilityPermission()
|
||||
|
||||
|
||||
// This will return the actual system state
|
||||
XCTAssertNotNil(hasPermission)
|
||||
|
||||
|
||||
print("Accessibility permission status: \(hasPermission)")
|
||||
}
|
||||
|
||||
|
||||
func testAccessibilityPermissionWithTrustedCheck() {
|
||||
// Test the AXIsProcessTrusted check
|
||||
let isTrusted = AXIsProcessTrusted()
|
||||
let hasPermission = permissionsChecker.hasAccessibilityPermission()
|
||||
|
||||
|
||||
// These should match
|
||||
XCTAssertEqual(isTrusted, hasPermission)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - checkAllPermissions Tests
|
||||
|
||||
|
||||
func testCheckAllPermissions() {
|
||||
// Test combined permissions check
|
||||
let (screenRecording, accessibility) = permissionsChecker.checkAllPermissions()
|
||||
|
||||
|
||||
// Both should return boolean values
|
||||
XCTAssertNotNil(screenRecording)
|
||||
XCTAssertNotNil(accessibility)
|
||||
|
||||
|
||||
// Verify individual checks match combined check
|
||||
XCTAssertEqual(screenRecording, permissionsChecker.hasScreenRecordingPermission())
|
||||
XCTAssertEqual(accessibility, permissionsChecker.hasAccessibilityPermission())
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Permission State Tests
|
||||
|
||||
|
||||
func testPermissionStateEncoding() throws {
|
||||
// Test that permission states can be properly encoded to JSON
|
||||
let serverStatus = ServerStatus(
|
||||
hasScreenRecordingPermission: true,
|
||||
hasAccessibilityPermission: false
|
||||
)
|
||||
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||
|
||||
|
||||
let data = try encoder.encode(serverStatus)
|
||||
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
|
||||
|
||||
|
||||
XCTAssertNotNil(json)
|
||||
XCTAssertEqual(json?["has_screen_recording_permission"] as? Bool, true)
|
||||
XCTAssertEqual(json?["has_accessibility_permission"] as? Bool, false)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Error Handling Tests
|
||||
|
||||
|
||||
func testPermissionDeniedError() {
|
||||
// Test error creation for permission denied
|
||||
let screenError = CaptureError.permissionDeniedScreenRecording
|
||||
let accessError = CaptureError.permissionDeniedAccessibility
|
||||
|
||||
|
||||
XCTAssertEqual(screenError.description, "Screen recording permission is required")
|
||||
XCTAssertEqual(accessError.description, "Accessibility permission is required")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Performance Tests
|
||||
|
||||
|
||||
func testPermissionCheckPerformance() {
|
||||
// Test that permission checks are fast
|
||||
measure {
|
||||
_ = permissionsChecker.checkAllPermissions()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Mock Tests (for CI/CD)
|
||||
|
||||
|
||||
func testMockPermissionScenarios() {
|
||||
// Test various permission scenarios for error handling
|
||||
|
||||
|
||||
// Scenario 1: No permissions
|
||||
var status = ServerStatus(
|
||||
hasScreenRecordingPermission: false,
|
||||
|
|
@ -125,7 +125,7 @@ final class PermissionsCheckerTests: XCTestCase {
|
|||
)
|
||||
XCTAssertFalse(status.hasScreenRecordingPermission)
|
||||
XCTAssertFalse(status.hasAccessibilityPermission)
|
||||
|
||||
|
||||
// Scenario 2: Only screen recording
|
||||
status = ServerStatus(
|
||||
hasScreenRecordingPermission: true,
|
||||
|
|
@ -133,7 +133,7 @@ final class PermissionsCheckerTests: XCTestCase {
|
|||
)
|
||||
XCTAssertTrue(status.hasScreenRecordingPermission)
|
||||
XCTAssertFalse(status.hasAccessibilityPermission)
|
||||
|
||||
|
||||
// Scenario 3: Both permissions
|
||||
status = ServerStatus(
|
||||
hasScreenRecordingPermission: true,
|
||||
|
|
@ -142,4 +142,4 @@ final class PermissionsCheckerTests: XCTestCase {
|
|||
XCTAssertTrue(status.hasScreenRecordingPermission)
|
||||
XCTAssertTrue(status.hasAccessibilityPermission)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,48 +1,48 @@
|
|||
import XCTest
|
||||
@testable import peekaboo
|
||||
import XCTest
|
||||
|
||||
final class WindowManagerTests: XCTestCase {
|
||||
var windowManager: WindowManager!
|
||||
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
windowManager = WindowManager()
|
||||
}
|
||||
|
||||
|
||||
override func tearDown() {
|
||||
windowManager = nil
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
|
||||
// MARK: - getAllWindows Tests
|
||||
|
||||
|
||||
func testGetAllWindows() throws {
|
||||
// Test getting all windows
|
||||
let windows = windowManager.getAllWindows()
|
||||
|
||||
|
||||
// Should have at least some windows (Finder, menu bar, etc.)
|
||||
XCTAssertGreaterThan(windows.count, 0)
|
||||
|
||||
|
||||
// Verify window properties
|
||||
for window in windows {
|
||||
XCTAssertNotNil(window[kCGWindowNumber])
|
||||
XCTAssertNotNil(window[kCGWindowBounds])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testGetAllWindowsContainsFinder() throws {
|
||||
// Finder should always have windows
|
||||
let windows = windowManager.getAllWindows()
|
||||
|
||||
|
||||
let finderWindows = windows.filter { window in
|
||||
(window[kCGWindowOwnerName] as? String) == "Finder"
|
||||
}
|
||||
|
||||
|
||||
XCTAssertGreaterThan(finderWindows.count, 0, "Should find at least one Finder window")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - getWindowsForApp Tests
|
||||
|
||||
|
||||
func testGetWindowsForAppByPID() throws {
|
||||
// Get Finder's PID
|
||||
let apps = NSWorkspace.shared.runningApplications
|
||||
|
|
@ -50,49 +50,49 @@ final class WindowManagerTests: XCTestCase {
|
|||
XCTFail("Finder not found")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let windows = windowManager.getWindowsForApp(pid: finder.processIdentifier, appName: nil)
|
||||
|
||||
|
||||
XCTAssertGreaterThan(windows.count, 0)
|
||||
|
||||
|
||||
// All windows should belong to Finder
|
||||
for window in windows {
|
||||
XCTAssertEqual(window[kCGWindowOwnerPID] as? pid_t, finder.processIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testGetWindowsForAppByName() throws {
|
||||
// Test filtering by app name
|
||||
let allWindows = windowManager.getAllWindows()
|
||||
let finderWindows = windowManager.getWindowsForApp(pid: nil, appName: "Finder")
|
||||
|
||||
|
||||
// Should have fewer windows when filtered
|
||||
XCTAssertLessThanOrEqual(finderWindows.count, allWindows.count)
|
||||
|
||||
|
||||
// All returned windows should be from Finder
|
||||
for window in finderWindows {
|
||||
XCTAssertEqual(window[kCGWindowOwnerName] as? String, "Finder")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testGetWindowsForNonExistentApp() {
|
||||
// Test with non-existent app
|
||||
let windows = windowManager.getWindowsForApp(pid: 99999, appName: nil)
|
||||
|
||||
|
||||
XCTAssertEqual(windows.count, 0)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Window Filtering Tests
|
||||
|
||||
|
||||
func testWindowFilteringExcludesInvisible() {
|
||||
// Get all windows including invisible ones
|
||||
let allWindows = windowManager.getAllWindows()
|
||||
|
||||
|
||||
// Check that we're not including windows that are off-screen or have zero size
|
||||
for window in allWindows {
|
||||
if let bounds = window[kCGWindowBounds] as? CFDictionary {
|
||||
let rect = CGRect(dictionaryRepresentation: bounds) ?? .zero
|
||||
|
||||
|
||||
// If window is included, it should have non-zero size
|
||||
if rect.width > 0 && rect.height > 0 {
|
||||
XCTAssertGreaterThan(rect.width, 0)
|
||||
|
|
@ -101,40 +101,40 @@ final class WindowManagerTests: XCTestCase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testWindowOrdering() {
|
||||
// Test that windows are ordered (typically by window level and order)
|
||||
let windows = windowManager.getAllWindows()
|
||||
|
||||
|
||||
guard windows.count > 1 else {
|
||||
XCTSkip("Need multiple windows to test ordering")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Windows should have window numbers
|
||||
for window in windows {
|
||||
XCTAssertNotNil(window[kCGWindowNumber])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Performance Tests
|
||||
|
||||
|
||||
func testGetAllWindowsPerformance() {
|
||||
// Test performance of getting all windows
|
||||
measure {
|
||||
_ = windowManager.getAllWindows()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testGetWindowsForAppPerformance() {
|
||||
// Test performance of filtered window retrieval
|
||||
measure {
|
||||
_ = windowManager.getWindowsForApp(pid: nil, appName: "Finder")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Helper Methods Tests
|
||||
|
||||
|
||||
func testCreateWindowInfo() {
|
||||
// Create a mock window dictionary
|
||||
let mockWindow: [CFString: Any] = [
|
||||
|
|
@ -151,7 +151,7 @@ final class WindowManagerTests: XCTestCase {
|
|||
kCGWindowIsOnscreen: true,
|
||||
kCGWindowLayer: 0
|
||||
]
|
||||
|
||||
|
||||
// Test window info creation
|
||||
let windowInfo = WindowInfo(
|
||||
windowID: 123,
|
||||
|
|
@ -162,7 +162,7 @@ final class WindowManagerTests: XCTestCase {
|
|||
isOnScreen: true,
|
||||
windowLevel: 0
|
||||
)
|
||||
|
||||
|
||||
XCTAssertEqual(windowInfo.windowID, 123)
|
||||
XCTAssertEqual(windowInfo.owningApplication, "TestApp")
|
||||
XCTAssertEqual(windowInfo.windowTitle, "Test Window")
|
||||
|
|
@ -171,4 +171,4 @@ final class WindowManagerTests: XCTestCase {
|
|||
XCTAssertEqual(windowInfo.bounds.width, 800)
|
||||
XCTAssertEqual(windowInfo.bounds.height, 600)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue