| | |
| | | func testAppIdentity() { |
| | | XCTAssertEqual(AlignerAppInfo.name, "Aligner") |
| | | XCTAssertEqual(AlignerAppInfo.bundleIdentifier, "com.ar.Aligner") |
| | | XCTAssertEqual(AlignerAppInfo.minimumMacOSVersion, "26.0") |
| | | XCTAssertEqual(AlignerAppInfo.minimumMacOSVersion, "14.0") |
| | | } |
| | | |
| | | func testPerformanceDiagnosticArchiveWriterCreatesInspectableArchive() throws { |
| | | let fileManager = FileManager.default |
| | | let rootURL = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) |
| | | let logURL = rootURL.appendingPathComponent("events.log") |
| | | let archiveURL = rootURL.appendingPathComponent("diagnostics.zip") |
| | | let extractionURL = rootURL.appendingPathComponent("extracted", isDirectory: true) |
| | | defer { try? fileManager.removeItem(at: rootURL) } |
| | | |
| | | try fileManager.createDirectory(at: rootURL, withIntermediateDirectories: true) |
| | | try "event=quickSwitch.snapshot.success durationMilliseconds=42\n".write(to: logURL, atomically: true, encoding: .utf8) |
| | | let summary = try JSONSerialization.data(withJSONObject: ["schemaVersion": 1], options: []) |
| | | |
| | | _ = try PerformanceDiagnosticArchiveWriter.write( |
| | | to: archiveURL, |
| | | summaryJSON: summary, |
| | | eventLogURLs: [logURL] |
| | | ) |
| | | XCTAssertTrue(fileManager.fileExists(atPath: archiveURL.path)) |
| | | |
| | | let unzipProcess = Process() |
| | | unzipProcess.executableURL = URL(fileURLWithPath: "/usr/bin/ditto") |
| | | unzipProcess.arguments = ["-x", "-k", archiveURL.path, extractionURL.path] |
| | | try unzipProcess.run() |
| | | unzipProcess.waitUntilExit() |
| | | XCTAssertEqual(unzipProcess.terminationStatus, 0) |
| | | let contentsURL = extractionURL.appendingPathComponent("Aligner-Diagnostics", isDirectory: true) |
| | | XCTAssertTrue(fileManager.fileExists(atPath: contentsURL.appendingPathComponent("summary.json").path)) |
| | | XCTAssertTrue(fileManager.fileExists(atPath: contentsURL.appendingPathComponent("performance-events.log").path)) |
| | | XCTAssertTrue(fileManager.fileExists(atPath: contentsURL.appendingPathComponent("README.txt").path)) |
| | | } |
| | | |
| | | func testPerformanceDiagnosticArchiveWriterDoesNotOverwriteExistingArchive() throws { |
| | | let fileManager = FileManager.default |
| | | let rootURL = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) |
| | | let archiveURL = rootURL.appendingPathComponent("diagnostics.zip") |
| | | defer { try? fileManager.removeItem(at: rootURL) } |
| | | |
| | | try fileManager.createDirectory(at: rootURL, withIntermediateDirectories: true) |
| | | try Data("existing archive".utf8).write(to: archiveURL) |
| | | let summary = try JSONSerialization.data(withJSONObject: ["schemaVersion": 1], options: []) |
| | | |
| | | XCTAssertThrowsError( |
| | | try PerformanceDiagnosticArchiveWriter.write( |
| | | to: archiveURL, |
| | | summaryJSON: summary, |
| | | eventLogURLs: [] |
| | | ) |
| | | ) |
| | | XCTAssertEqual(try Data(contentsOf: archiveURL), Data("existing archive".utf8)) |
| | | } |
| | | |
| | | func testPerformanceDiagnosticArchiveWriterFiltersSensitiveLogFields() throws { |
| | | let fileManager = FileManager.default |
| | | let rootURL = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) |
| | | let sourceLogURL = rootURL.appendingPathComponent("events.log") |
| | | let archiveURL = rootURL.appendingPathComponent("diagnostics.zip") |
| | | let extractionURL = rootURL.appendingPathComponent("extracted", isDirectory: true) |
| | | defer { try? fileManager.removeItem(at: rootURL) } |
| | | |
| | | try fileManager.createDirectory(at: rootURL, withIntermediateDirectories: true) |
| | | try "event=quickSwitch.snapshot.success ts=2026-08-14T00:00:00Z durationMilliseconds=42 reportPathBasename=private-notes.txt title=secret\n".write(to: sourceLogURL, atomically: true, encoding: .utf8) |
| | | let summary = try JSONSerialization.data(withJSONObject: ["schemaVersion": 1], options: []) |
| | | _ = try PerformanceDiagnosticArchiveWriter.write( |
| | | to: archiveURL, |
| | | summaryJSON: summary, |
| | | eventLogURLs: [sourceLogURL] |
| | | ) |
| | | |
| | | let unzipProcess = Process() |
| | | unzipProcess.executableURL = URL(fileURLWithPath: "/usr/bin/ditto") |
| | | unzipProcess.arguments = ["-x", "-k", archiveURL.path, extractionURL.path] |
| | | try unzipProcess.run() |
| | | unzipProcess.waitUntilExit() |
| | | XCTAssertEqual(unzipProcess.terminationStatus, 0) |
| | | let exportedLogURL = extractionURL |
| | | .appendingPathComponent("Aligner-Diagnostics", isDirectory: true) |
| | | .appendingPathComponent("performance-events.log") |
| | | let exportedLog = try String(contentsOf: exportedLogURL, encoding: .utf8) |
| | | XCTAssertTrue(exportedLog.contains("event=quickSwitch.snapshot.success")) |
| | | XCTAssertTrue(exportedLog.contains("durationMilliseconds=42")) |
| | | XCTAssertFalse(exportedLog.contains("private-notes.txt")) |
| | | XCTAssertFalse(exportedLog.contains("title=secret")) |
| | | } |
| | | |
| | | func testRound0OnlyDefinesQuickSwitchEntryPoint() { |
| | |
| | | subroleDescription: "standard" |
| | | ) |
| | | ) |
| | | } |
| | | |
| | | func testWindowEnumerationPolicyRejectsLowConfidenceAXOnlyRegularWindows() { |
| | | XCTAssertFalse(WindowEnumerationPolicy.shouldIncludeAXOnlyRecord( |
| | | identifierSource: .cgWindow, |
| | | isMinimized: false, |
| | | isFullscreen: false, |
| | | spaceIDs: [] |
| | | )) |
| | | XCTAssertTrue(WindowEnumerationPolicy.shouldIncludeAXOnlyRecord( |
| | | identifierSource: .cgWindow, |
| | | isMinimized: true, |
| | | isFullscreen: false, |
| | | spaceIDs: [] |
| | | )) |
| | | XCTAssertTrue(WindowEnumerationPolicy.shouldIncludeAXOnlyRecord( |
| | | identifierSource: .cgWindow, |
| | | isMinimized: false, |
| | | isFullscreen: true, |
| | | spaceIDs: [42] |
| | | )) |
| | | XCTAssertFalse(WindowEnumerationPolicy.shouldIncludeAXOnlyRecord( |
| | | identifierSource: .syntheticAX, |
| | | isMinimized: false, |
| | | isFullscreen: false, |
| | | spaceIDs: [] |
| | | )) |
| | | } |
| | | |
| | | func testMinimizedWindowFallbackPolicyAvoidsOccupiedSyntheticIDCollisions() { |
| | |
| | | XCTAssertTrue(attributed[1].isFullscreen) |
| | | } |
| | | |
| | | func testFinderTabSpaceAttributionRejectsContainingHostsWithDifferentSize() { |
| | | let finderApp = AlignerApp( |
| | | bundleIdentifier: "com.apple.finder", |
| | | name: "访达", |
| | | category: .finder, |
| | | processIdentifier: 74678 |
| | | ) |
| | | let splitRightFrame = CGRect(x: 960, y: 0, width: 960, height: 1080) |
| | | let fullDisplayFrame = CGRect(x: 0, y: 0, width: 1920, height: 1080) |
| | | let splitHost = WindowEnumerationRecord( |
| | | id: 33112, |
| | | app: finderApp, |
| | | title: "下载", |
| | | size: splitRightFrame.size, |
| | | frame: splitRightFrame, |
| | | subrole: .standard, |
| | | isFullscreen: true, |
| | | hasAXBacking: true, |
| | | spaceIDs: [843] |
| | | ) |
| | | let containingHost = WindowEnumerationRecord( |
| | | id: 41557, |
| | | app: finderApp, |
| | | title: "应用程序", |
| | | size: fullDisplayFrame.size, |
| | | frame: fullDisplayFrame, |
| | | subrole: .standard, |
| | | isFullscreen: true, |
| | | hasAXBacking: true, |
| | | spaceIDs: [1112] |
| | | ) |
| | | let inactiveTab = WindowEnumerationRecord( |
| | | id: 42286, |
| | | app: finderApp, |
| | | title: "Appcache", |
| | | size: splitRightFrame.size, |
| | | frame: splitRightFrame, |
| | | subrole: .standard, |
| | | hasAXBacking: false, |
| | | isOnscreen: false |
| | | ) |
| | | |
| | | let attributed = FinderTabSpaceAttributionPolicy.attributedRecords([ |
| | | inactiveTab, |
| | | containingHost, |
| | | splitHost |
| | | ]) |
| | | |
| | | XCTAssertEqual(attributed[0].spaceIDs, [843]) |
| | | XCTAssertTrue(attributed[0].isFullscreen) |
| | | } |
| | | |
| | | func testWindowEnumerationPolicyKeepsMinimizedAndFullscreenCGOnlyOffscreenWindows() { |
| | | let minimized = makeWindowRecord( |
| | | title: "Minimized Document.md", |
| | |
| | | XCTAssertTrue(templates.allSatisfy { $0.contentRows > 0 }) |
| | | } |
| | | |
| | | func testSkeletonThumbnailPaletteStaysQuietForFallbackState() { |
| | | XCTAssertLessThanOrEqual(SkeletonThumbnailPalette.headerAlpha, 0.10) |
| | | XCTAssertLessThanOrEqual(SkeletonThumbnailPalette.contentRowAlpha, 0.08) |
| | | XCTAssertLessThanOrEqual(SkeletonThumbnailPalette.accentStripeAlpha, 0.30) |
| | | XCTAssertGreaterThanOrEqual(SkeletonThumbnailPalette.titleBandAlpha, 0.80) |
| | | } |
| | | |
| | | @MainActor |
| | | func testNativeSkeletonThumbnailProviderProducesValidImages() { |
| | | let provider = NativeSkeletonThumbnailProvider() |