95 lines
3.0 KiB
Swift
Raw Permalink Normal View History

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)
}
}