集成高德 SDK 并替换所有定位相关的 CoreLocation 与 MapKit

This commit is contained in:
2026-07-07 11:49:22 +08:00
parent 3acbf6315b
commit 8a4a30111c
29 changed files with 748 additions and 240 deletions

View File

@ -0,0 +1,51 @@
//
// AMapBootstrapTests.swift
// suixinkanTests
//
import XCTest
@testable import suixinkan
/// SDK gate
final class AMapBootstrapTests: XCTestCase {
private var defaults: UserDefaults!
private var appStore: AppStore!
override func setUp() {
super.setUp()
AMapBootstrap.resetForTesting()
defaults = UserDefaults(suiteName: "AMapBootstrapTests")!
defaults.removePersistentDomain(forName: "AMapBootstrapTests")
appStore = AppStore(defaults: defaults)
}
override func tearDown() {
AMapBootstrap.resetForTesting()
super.tearDown()
}
func testConfigureReturnsFalseWhenPrivacyNotAccepted() {
appStore.privacyAgreementAccepted = false
XCTAssertFalse(AMapBootstrap.configureIfNeeded(appStore: appStore))
XCTAssertFalse(AMapBootstrap.isConfigured)
}
func testConfigureIsIdempotentWhenPrivacyAccepted() {
appStore.privacyAgreementAccepted = true
XCTAssertTrue(AMapBootstrap.configureIfNeeded(appStore: appStore))
XCTAssertTrue(AMapBootstrap.isConfigured)
XCTAssertTrue(AMapBootstrap.configureIfNeeded(appStore: appStore))
XCTAssertTrue(AMapBootstrap.isConfigured)
}
func testRequireConfiguredThrowsWhenPrivacyNotAccepted() {
appStore.privacyAgreementAccepted = false
XCTAssertThrowsError(try AMapBootstrap.requireConfigured(appStore: appStore)) { error in
XCTAssertEqual(error as? LocationProviderError, .privacyNotAccepted)
}
}
}

View File

@ -0,0 +1,60 @@
//
// LocationProviderTests.swift
// suixinkanTests
//
import CoreLocation
import XCTest
@testable import suixinkan
/// ViewModel
final class LocationProviderTests: XCTestCase {
private var defaults: UserDefaults!
private var appStore: AppStore!
override func setUp() {
super.setUp()
defaults = UserDefaults(suiteName: "LocationProviderTests")!
defaults.removePersistentDomain(forName: "LocationProviderTests")
appStore = AppStore(defaults: defaults)
}
func testScenicSelectionUsesInjectedProviderSnapshot() async {
let mock = MockLocationProvider()
mock.snapshot = HomeLocationSnapshot(latitude: 30.2, longitude: 120.1, address: "杭州")
appStore.saveRoleScenicList([
ScenicInfo(id: 1, name: "西湖", status: 1, location: ScenicLocationInfo(lng: 120.1, lat: 30.2, address: "杭州"), coverImg: nil),
])
let viewModel = ScenicSelectionViewModel(appStore: appStore, locationProvider: mock)
var message: String?
viewModel.onShowMessage = { message = $0 }
await viewModel.startLocation()
XCTAssertEqual(viewModel.currentLocationText, "杭州")
XCTAssertNil(message)
}
func testLocationReportViewModelUsesInjectedReverseGeocode() async {
let mock = MockLocationProvider()
mock.reverseGeocodeResult = "标记地址"
let viewModel = LocationReportViewModel(locationProvider: mock)
viewModel.toggleMarking()
viewModel.setMarkerLocation(latitude: 30.1, longitude: 120.2)
try? await Task.sleep(nanoseconds: 200_000_000)
XCTAssertEqual(viewModel.markerAddress, "标记地址")
}
func testMockLocationProviderCoordinate() async throws {
let mock = MockLocationProvider()
mock.coordinate = CLLocationCoordinate2D(latitude: 31.0, longitude: 121.0)
let coordinate = try await mock.requestCoordinate()
XCTAssertEqual(coordinate.latitude, 31.0, accuracy: 0.0001)
XCTAssertEqual(coordinate.longitude, 121.0, accuracy: 0.0001)
}
}

View File

@ -0,0 +1,30 @@
//
// MockLocationProvider.swift
// suixinkanTests
//
import CoreLocation
@testable import suixinkan
///
final class MockLocationProvider: LocationProviding, @unchecked Sendable {
var snapshot = HomeLocationSnapshot(latitude: 39.9087, longitude: 116.3975, address: "北京市东城区")
var coordinate = CLLocationCoordinate2D(latitude: 39.9087, longitude: 116.3975)
var reverseGeocodeResult = "北京市东城区"
var requestSnapshotError: Error?
var requestCoordinateError: Error?
func requestSnapshot() async throws -> HomeLocationSnapshot {
if let requestSnapshotError { throw requestSnapshotError }
return snapshot
}
func requestCoordinate() async throws -> CLLocationCoordinate2D {
if let requestCoordinateError { throw requestCoordinateError }
return coordinate
}
func reverseGeocode(latitude: Double, longitude: Double) async -> String {
reverseGeocodeResult
}
}