95 lines
3.0 KiB
Swift
95 lines
3.0 KiB
Swift
|
import Foundation
|
|||
|
import CoreLocation
|
|||
|
|
|||
|
/// A `CLLocationManager` subclass allowing mocking in tests.
|
|||
|
final class MockCLLocationManager: CLLocationManager {
|
|||
|
|
|||
|
private var _heading: CLHeading?
|
|||
|
override var heading: CLHeading? { _heading }
|
|||
|
|
|||
|
private var _location: CLLocation?
|
|||
|
override var location: CLLocation? { _location }
|
|||
|
|
|||
|
override class func locationServicesEnabled() -> Bool { true }
|
|||
|
|
|||
|
private var _authorizationStatus: CLAuthorizationStatus = .authorizedAlways
|
|||
|
override var authorizationStatus: CLAuthorizationStatus {
|
|||
|
return _authorizationStatus
|
|||
|
}
|
|||
|
|
|||
|
override func startUpdatingLocation() {
|
|||
|
isUpdatingLocation = true
|
|||
|
}
|
|||
|
|
|||
|
override func stopUpdatingLocation() {
|
|||
|
isUpdatingLocation = false
|
|||
|
}
|
|||
|
|
|||
|
override func startUpdatingHeading() {
|
|||
|
isUpdatingHeading = true
|
|||
|
}
|
|||
|
|
|||
|
override func stopUpdatingHeading() {
|
|||
|
isUpdatingHeading = false
|
|||
|
}
|
|||
|
|
|||
|
override func requestWhenInUseAuthorization() {
|
|||
|
isRequestedForAuthorization = true
|
|||
|
}
|
|||
|
|
|||
|
// Empty overrides preventing the real interaction with the superclass.
|
|||
|
override func requestAlwaysAuthorization() { }
|
|||
|
override func startMonitoringSignificantLocationChanges() { }
|
|||
|
override func stopMonitoringSignificantLocationChanges() { }
|
|||
|
|
|||
|
// MARK: - Test properties
|
|||
|
|
|||
|
var isUpdatingLocation: Bool = false
|
|||
|
var isUpdatingHeading: Bool = false
|
|||
|
var isRequestedForAuthorization: Bool?
|
|||
|
|
|||
|
/// Simulates a new location being emitted. Updates the `location` property
|
|||
|
/// and notifies the delegate.
|
|||
|
///
|
|||
|
/// - Parameter location: The new location used.
|
|||
|
///
|
|||
|
func simulateUpdate(location: CLLocation) {
|
|||
|
_location = location
|
|||
|
delegate?.locationManager?(self, didUpdateLocations: [location])
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// Simulates a new heading being emitted. Updates the `heading` property
|
|||
|
/// and notifies the delegate.
|
|||
|
///
|
|||
|
/// - Parameter heading: The new heading used.
|
|||
|
///
|
|||
|
func simulateUpdate(heading: CLHeading) {
|
|||
|
_heading = heading
|
|||
|
delegate?.locationManager?(self, didUpdateHeading: heading)
|
|||
|
}
|
|||
|
|
|||
|
/// Simulates the location manager failing with an error. Notifies the delegate with
|
|||
|
/// the provided error.
|
|||
|
///
|
|||
|
/// - Parameter error: The error used for the delegate callback.
|
|||
|
///
|
|||
|
func simulate(error: Error) {
|
|||
|
delegate?.locationManager?(self, didFailWithError: error)
|
|||
|
}
|
|||
|
|
|||
|
/// Updates the `authorizationStatus` value and notifies the delegate.
|
|||
|
///
|
|||
|
/// - Important: ⚠️ `authorizationStatus` is a static variable. Calling
|
|||
|
/// the `simulate(authorizationStatus:)` function will change the value for all
|
|||
|
/// instances of `MockCLLocationManager`. The `didChangeAuthorization` delegate
|
|||
|
/// method is called only on the delegate of this instance.
|
|||
|
///
|
|||
|
/// - Parameter authorizationStatus: The new authorization status.
|
|||
|
///
|
|||
|
func simulate(authorizationStatus: CLAuthorizationStatus) {
|
|||
|
_authorizationStatus = authorizationStatus
|
|||
|
delegate?.locationManagerDidChangeAuthorization?(self)
|
|||
|
}
|
|||
|
}
|