import XCTest @testable import MCT final class LayoutEngineTests: XCTestCase { let screenBounds = CGRect(x: 0, y: 0, width: 1920, height: 1080) // MARK: - Helpers private func makeWindow( id: CGWindowID, title: String, appName: String, bundleID: String ) -> WindowInfo { WindowInfo( windowID: id, title: title, appName: appName, appBundleID: bundleID, appIcon: nil, frame: CGRect(x: 0, y: 0, width: 800, height: 600), pid: pid_t(id), isOnScreen: true, thumbnail: nil ) } private func makeSnapshot(windows: [WindowInfo]) -> WindowSnapshot { let groups = WindowEnumerator.groupWindows(windows) return WindowSnapshot(groups: groups) } // MARK: - Grouping Tests func testGroupingByApp() { let windows = [ makeWindow(id: 1, title: "Doc 1", appName: "Safari", bundleID: "com.apple.Safari"), makeWindow(id: 2, title: "Doc 2", appName: "Safari", bundleID: "com.apple.Safari"), makeWindow(id: 3, title: "Main", appName: "Xcode", bundleID: "com.apple.dt.Xcode"), ] let groups = WindowEnumerator.groupWindows(windows) XCTAssertEqual(groups.count, 2) // Safari has frontmost window (index 0), so it should be first XCTAssertEqual(groups[0].appBundleID, "com.apple.Safari") XCTAssertEqual(groups[0].windows.count, 2) XCTAssertEqual(groups[1].appBundleID, "com.apple.dt.Xcode") XCTAssertEqual(groups[1].windows.count, 1) } func testGroupOrderingFrontmostFirst() { let windows = [ makeWindow(id: 1, title: "Main", appName: "Xcode", bundleID: "com.apple.dt.Xcode"), makeWindow(id: 2, title: "Tab 1", appName: "Safari", bundleID: "com.apple.Safari"), makeWindow(id: 3, title: "Tab 2", appName: "Safari", bundleID: "com.apple.Safari"), ] let groups = WindowEnumerator.groupWindows(windows) // Xcode has the frontmost window (index 0), so it should be first XCTAssertEqual(groups[0].appBundleID, "com.apple.dt.Xcode") XCTAssertEqual(groups[1].appBundleID, "com.apple.Safari") } // MARK: - Layout Tests func testLayoutProducesItemsForAllWindows() { let windows = [ makeWindow(id: 1, title: "W1", appName: "App", bundleID: "com.test.app"), makeWindow(id: 2, title: "W2", appName: "App", bundleID: "com.test.app"), makeWindow(id: 3, title: "W3", appName: "Other", bundleID: "com.test.other"), ] let engine = LayoutEngine() let snapshot = makeSnapshot(windows: windows) let result = engine.layout(snapshot: snapshot, screenBounds: screenBounds) XCTAssertEqual(result.items.count, 3) XCTAssertEqual(result.headers.count, 2) } func testLayoutItemsWithinScreenBounds() { let windows = (1...6).map { i in makeWindow(id: CGWindowID(i), title: "Win \(i)", appName: "App", bundleID: "com.test.app") } let engine = LayoutEngine() let snapshot = makeSnapshot(windows: windows) let result = engine.layout(snapshot: snapshot, screenBounds: screenBounds) for item in result.items { XCTAssertTrue( screenBounds.contains(CGPoint(x: item.frame.midX, y: item.frame.midY)), "Item center \(item.frame) should be within screen bounds \(screenBounds)" ) } } // MARK: - Fingerprint / Stability Tests func testSnapshotFingerprint() { let windows = [ makeWindow(id: 1, title: "Doc", appName: "Safari", bundleID: "com.apple.Safari"), makeWindow(id: 2, title: "Main", appName: "Xcode", bundleID: "com.apple.dt.Xcode"), ] let snapshot = makeSnapshot(windows: windows) XCTAssertEqual(snapshot.fingerprint.count, 2) XCTAssertTrue(snapshot.fingerprint.contains("com.apple.Safari|Doc")) XCTAssertTrue(snapshot.fingerprint.contains("com.apple.dt.Xcode|Main")) } func testOverlapRatioIdentical() { let windows = [ makeWindow(id: 1, title: "Doc", appName: "Safari", bundleID: "com.apple.Safari"), ] let s1 = makeSnapshot(windows: windows) let s2 = makeSnapshot(windows: windows) XCTAssertEqual(s1.overlapRatio(with: s2), 1.0) } func testOverlapRatioDisjoint() { let w1 = [makeWindow(id: 1, title: "A", appName: "App1", bundleID: "com.a")] let w2 = [makeWindow(id: 2, title: "B", appName: "App2", bundleID: "com.b")] let s1 = makeSnapshot(windows: w1) let s2 = makeSnapshot(windows: w2) XCTAssertEqual(s1.overlapRatio(with: s2), 0.0) } func testOverlapRatioPartial() { let shared = makeWindow(id: 1, title: "Shared", appName: "App", bundleID: "com.app") let w1 = [shared, makeWindow(id: 2, title: "Only1", appName: "X", bundleID: "com.x")] let w2 = [shared, makeWindow(id: 3, title: "Only2", appName: "Y", bundleID: "com.y")] let s1 = makeSnapshot(windows: w1) let s2 = makeSnapshot(windows: w2) // intersection = 1 (shared), union = 3 (shared, Only1, Only2) XCTAssertEqual(s1.overlapRatio(with: s2), 1.0 / 3.0, accuracy: 0.001) } // MARK: - Stability Tests func testStableLayoutSameWindows() { let windows = [ makeWindow(id: 1, title: "W1", appName: "App", bundleID: "com.test"), makeWindow(id: 2, title: "W2", appName: "App", bundleID: "com.test"), ] let engine = LayoutEngine() let snapshot = makeSnapshot(windows: windows) let result1 = engine.layout(snapshot: snapshot, screenBounds: screenBounds) let result2 = engine.layout(snapshot: snapshot, screenBounds: screenBounds) // Same windows should produce same positions for (item1, item2) in zip(result1.items, result2.items) { XCTAssertEqual(item1.frame.origin.x, item2.frame.origin.x, accuracy: 1.0) XCTAssertEqual(item1.frame.origin.y, item2.frame.origin.y, accuracy: 1.0) } } // MARK: - Geometry Tests func testThumbnailSizeFitsOnScreen() { let (size, cols) = LayoutGeometry.uniformThumbnailSize( groupWindowCounts: [4, 4, 4, 4, 4], availableWidth: 1920 - LayoutGeometry.margin * 2, availableHeight: 1080 - LayoutGeometry.margin * 2 ) XCTAssertGreaterThan(size.width, 0) XCTAssertGreaterThan(cols, 0) } func testAspectFit() { let fitted = LayoutGeometry.aspectFit( source: CGSize(width: 1600, height: 900), target: CGSize(width: 320, height: 200) ) XCTAssertLessThanOrEqual(fitted.width, 320) XCTAssertLessThanOrEqual(fitted.height, 200) // Aspect ratio should be preserved let sourceRatio = 1600.0 / 900.0 let fittedRatio = fitted.width / fitted.height XCTAssertEqual(sourceRatio, fittedRatio, accuracy: 0.01) } }