import XCTest @testable import Flights /// Guard test against a regression where the dead-code "Selftest" block in /// `RootView.swift` (a Task.detached that called /// `routeExplorer.searchSchedule` on app launch and printed results) gets /// re-introduced. That block touched the broken `RouteExplorerClient` and /// fired off a detached task at startup — exactly the shape we want to /// keep out of the launch path. /// /// Strategy: locate `RootView.swift` on disk and assert none of the /// fingerprint substrings are present. We try a couple of paths because /// the working directory during `xcodebuild test` is not stable. final class SelftestRemovalTests: XCTestCase { /// Fingerprints that uniquely identify the dead-code block. private static let forbiddenSubstrings: [String] = [ "[Selftest]", "routeExplorer.searchSchedule", "Task.detached" ] func test_rootView_doesNotContainSelftestDeadCode() throws { guard let source = Self.loadRootViewSource() else { // We couldn't locate the file from the test bundle's vantage // point. Don't silently pass — surface it as a skip so the // dev knows to do a manual check. // manual check: open Flights/Views/RootView.swift and confirm // none of `[Selftest]`, `routeExplorer.searchSchedule`, or // `Task.detached` appear in it. throw XCTSkip("Could not locate RootView.swift from the test bundle; manual check required.") } for needle in Self.forbiddenSubstrings { XCTAssertFalse( source.contains(needle), "RootView.swift still contains forbidden dead-code fingerprint: \(needle)" ) } } // MARK: - File location /// Try several strategies to find `RootView.swift` on disk. /// Order: explicit env var → walking up from the test bundle → a known /// absolute project path → walking up from #file. private static func loadRootViewSource() -> String? { let fm = FileManager.default var candidates: [String] = [] // 1. Env override (useful for CI or weird scheme configs). if let envRoot = ProcessInfo.processInfo.environment["FLIGHTS_PROJECT_ROOT"] { candidates.append((envRoot as NSString).appendingPathComponent("Flights/Views/RootView.swift")) } // 2. Walk up from the test bundle until we find a sibling `Flights` dir. let bundleURL = Bundle(for: SelftestRemovalTests.self).bundleURL var dir = bundleURL.deletingLastPathComponent() for _ in 0..<8 { let guess = dir.appendingPathComponent("Flights/Views/RootView.swift").path candidates.append(guess) dir = dir.deletingLastPathComponent() } // 3. Known absolute path on this dev machine (best-effort fallback). candidates.append("/Users/m4mini/Desktop/code/Flights/Flights/Views/RootView.swift") // 4. Walk up from this source file's location. let thisFile = URL(fileURLWithPath: #filePath) var srcDir = thisFile.deletingLastPathComponent() for _ in 0..<6 { let guess = srcDir.appendingPathComponent("Flights/Views/RootView.swift").path candidates.append(guess) srcDir = srcDir.deletingLastPathComponent() } for path in candidates where fm.fileExists(atPath: path) { if let contents = try? String(contentsOfFile: path, encoding: .utf8) { return contents } } return nil } }