diff --git a/Xcodes/Backend/AppState.swift b/Xcodes/Backend/AppState.swift index d8abd11..e665d55 100644 --- a/Xcodes/Backend/AppState.swift +++ b/Xcodes/Backend/AppState.swift @@ -384,16 +384,15 @@ class AppState: ObservableObject { } // Map all of the available versions into Xcode values that join available and installed Xcode data for display. - allXcodes = allAvailableXcodeVersions - .sorted(by: >) - .map { availableXcodeVersion in + allXcodes = zip(allAvailableXcodeVersions, availableXcodes) + .sorted(by: { $0.0 > $1.0 }) + .map { availableXcodeVersion, availableXcode in let installedXcode = installedXcodes.first(where: { installedXcode in // Checking equality for Xcode Releases version availableXcodeVersion == installedXcode.version || // Check more carefully for Apple version availableXcodeVersion.isEquivalentForDeterminingIfInstalled(toInstalled: installedXcode.version) }) - let availableXcode = availableXcodes.first { $0.version == availableXcodeVersion } // If the existing install state is "installing", keep it let existingXcodeInstallState = allXcodes.first { $0.version == availableXcodeVersion && $0.installing }?.installState @@ -406,10 +405,10 @@ class AppState: ObservableObject { selected: installedXcode != nil && selectedXcodePath?.hasPrefix(installedXcode!.path.string) == true, path: installedXcode?.path.string, icon: (installedXcode?.path.string).map(NSWorkspace.shared.icon(forFile:)), - requiredMacOSVersion: availableXcode?.requiredMacOSVersion, - releaseNotesURL: availableXcode?.releaseNotesURL, - sdks: availableXcode?.sdks, - compilers: availableXcode?.compilers + requiredMacOSVersion: availableXcode.requiredMacOSVersion, + releaseNotesURL: availableXcode.releaseNotesURL, + sdks: availableXcode.sdks, + compilers: availableXcode.compilers ) } } diff --git a/XcodesTests/AppStateUpdateTests.swift b/XcodesTests/AppStateUpdateTests.swift index 1e33645..13983b9 100644 --- a/XcodesTests/AppStateUpdateTests.swift +++ b/XcodesTests/AppStateUpdateTests.swift @@ -65,4 +65,27 @@ class AppStateUpdateTests: XCTestCase { XCTAssertEqual(subject.allXcodes[0].selected, false) XCTAssertEqual(subject.allXcodes[0].path, "/Applications/Xcode-0.0.0.app") } + + func testAdjustedVersionsAreUsedToLookupAvailableXcode() throws { + subject.allXcodes = [ + ] + + subject.updateAllXcodes( + availableXcodes: [ + // Note "GM" prerelease identifier + AvailableXcode(version: Version("0.0.0-GM+ABC123")!, url: URL(string: "https://apple.com/xcode.xip")!, filename: "mock.xip", releaseDate: nil, sdks: .init(iOS: .init("14.3"))) + ], + installedXcodes: [ + InstalledXcode(path: Path("/Applications/Xcode-0.0.0.app")!)! + ], + selectedXcodePath: nil + ) + + XCTAssertEqual(subject.allXcodes[0].version, Version("0.0.0+ABC123")!) + XCTAssertEqual(subject.allXcodes[0].installState, .installed) + XCTAssertEqual(subject.allXcodes[0].selected, false) + XCTAssertEqual(subject.allXcodes[0].path, "/Applications/Xcode-0.0.0.app") + // XCModel types aren't equatable, so just check for non-nil for now + XCTAssertNotNil(subject.allXcodes[0].sdks) + } }