Skip to content
This repository was archived by the owner on Jul 10, 2025. It is now read-only.

Commit 717f7f2

Browse files
committed
tests
1 parent 73af901 commit 717f7f2

File tree

14 files changed

+386
-184
lines changed

14 files changed

+386
-184
lines changed

Marlin/Marlin.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@
149149
F75324BE298197E4005C509F /* OnboardingViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75324BD298197E4005C509F /* OnboardingViewTests.swift */; };
150150
F75324C02983272A005C509F /* MarlinCompactWidthViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75324BF2983272A005C509F /* MarlinCompactWidthViewTests.swift */; };
151151
F75324C229833BBB005C509F /* MalrinMapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75324C129833BBB005C509F /* MalrinMapTests.swift */; };
152+
F75324C529885521005C509F /* SearchResultsMapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75324C429885521005C509F /* SearchResultsMapTests.swift */; };
153+
F75324C72989854F005C509F /* UserTrackingButtonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75324C62989854F005C509F /* UserTrackingButtonTests.swift */; };
152154
F75F81D529526E9C0062A708 /* AsamSummaryViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75F81D429526E9C0062A708 /* AsamSummaryViewTests.swift */; };
153155
F75F81D8295DE0EF0062A708 /* AboutCellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75F81D7295DE0EF0062A708 /* AboutCellTests.swift */; };
154156
F75F81DA295DE4640062A708 /* AboutViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75F81D9295DE4640062A708 /* AboutViewTests.swift */; };
@@ -493,6 +495,8 @@
493495
F75324BD298197E4005C509F /* OnboardingViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewTests.swift; sourceTree = "<group>"; };
494496
F75324BF2983272A005C509F /* MarlinCompactWidthViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarlinCompactWidthViewTests.swift; sourceTree = "<group>"; };
495497
F75324C129833BBB005C509F /* MalrinMapTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MalrinMapTests.swift; sourceTree = "<group>"; };
498+
F75324C429885521005C509F /* SearchResultsMapTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsMapTests.swift; sourceTree = "<group>"; };
499+
F75324C62989854F005C509F /* UserTrackingButtonTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserTrackingButtonTests.swift; sourceTree = "<group>"; };
496500
F75F81D229526D5C0062A708 /* libKIF.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libKIF.a; sourceTree = BUILT_PRODUCTS_DIR; };
497501
F75F81D429526E9C0062A708 /* AsamSummaryViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsamSummaryViewTests.swift; sourceTree = "<group>"; };
498502
F75F81D7295DE0EF0062A708 /* AboutCellTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutCellTests.swift; sourceTree = "<group>"; };
@@ -1072,6 +1076,14 @@
10721076
path = Onboarding;
10731077
sourceTree = "<group>";
10741078
};
1079+
F75324C32988550F005C509F /* Mixins */ = {
1080+
isa = PBXGroup;
1081+
children = (
1082+
F75324C429885521005C509F /* SearchResultsMapTests.swift */,
1083+
);
1084+
path = Mixins;
1085+
sourceTree = "<group>";
1086+
};
10751087
F75F81D6295DE0DD0062A708 /* Settings */ = {
10761088
isa = PBXGroup;
10771089
children = (
@@ -1337,9 +1349,11 @@
13371349
F7D8FA312936C06600E7D0A1 /* Map */ = {
13381350
isa = PBXGroup;
13391351
children = (
1352+
F75324C32988550F005C509F /* Mixins */,
13401353
F7D8FA322936C07100E7D0A1 /* Annotation */,
13411354
F73D9E242970E54C008AF40D /* MapSettingsTests.swift */,
13421355
F75324C129833BBB005C509F /* MalrinMapTests.swift */,
1356+
F75324C62989854F005C509F /* UserTrackingButtonTests.swift */,
13431357
);
13441358
path = Map;
13451359
sourceTree = "<group>";
@@ -1932,6 +1946,7 @@
19321946
F75F81E2295F70A50062A708 /* BooleanFilterTests.swift in Sources */,
19331947
F72D89022979BCA300D022FB /* ModuDetailViewTests.swift in Sources */,
19341948
F72D891B297F449C00D022FB /* DFRSDataTests.swift in Sources */,
1949+
F75324C72989854F005C509F /* UserTrackingButtonTests.swift in Sources */,
19351950
F727A697284E606F00BD728A /* KIF+extensions.swift in Sources */,
19361951
F727A691284E605800BD728A /* MarlinTests.swift in Sources */,
19371952
F73ABC8D295250C70085EDC5 /* DataSourcePropertyFilterViewModelTests.swift in Sources */,
@@ -1956,6 +1971,7 @@
19561971
F73ABC8E295250C70085EDC5 /* DataSourceSortTests.swift in Sources */,
19571972
F75324B629806329005C509F /* DFRSDetailViewTests.swift in Sources */,
19581973
F72EAABC291C138000AC6026 /* PortDataTests.swift in Sources */,
1974+
F75324C529885521005C509F /* SearchResultsMapTests.swift in Sources */,
19591975
F72D890E2979F48E00D022FB /* NavigationalWarningDetailTests.swift in Sources */,
19601976
F75324C229833BBB005C509F /* MalrinMapTests.swift in Sources */,
19611977
F72EAAC1291C274100AC6026 /* DifferentialGPSStationDataTests.swift in Sources */,

Marlin/Marlin/Extensions/CLLocationCoordinate2DExtensions.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,6 @@ extension CLLocationCoordinate2D {
557557
let range = Range(nsrange, in: coordinateString),
558558
!range.isEmpty
559559
{
560-
print("xxx component \(component)")
561-
print("xxx value \(coordinateString[range])")
562560
if component == "latdirection" {
563561
latmultiplier = "NEO".contains(coordinateString[range]) ? 1.0 : -1.0
564562
} else if component == "latdeg" {

Marlin/Marlin/Location/LocationManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import geopackage_ios
1313
import mgrs_ios
1414
import ExceptionCatcher
1515

16-
protocol LocationManagerProtocol {
16+
protocol LocationManagerProtocol: ObservableObject {
1717
var locationStatus: CLAuthorizationStatus? { get set }
1818
func requestAuthorization()
1919
}

Marlin/Marlin/Map/Mixins/SearchResultsMap.swift

Lines changed: 5 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class SearchResultsMap: NSObject, MapMixin {
5252
mapView.addAnnotations(self.annotations)
5353
}
5454
.store(in: &cancellable)
55-
55+
// TODO: this seems like the wrong place for this
5656
let region = UserDefaults.standard.mapRegion
5757
if CLLocationCoordinate2DIsValid(region.center) {
5858
if MKUserTrackingMode(rawValue: marlinMap.mapState.userTrackingMode) ?? MKUserTrackingMode.none == .none {
@@ -77,7 +77,6 @@ class SearchResultsMap: NSObject, MapMixin {
7777
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "placemark", for: annotation) as? MKMarkerAnnotationView {
7878
annotationView.isEnabled = true
7979
annotationView.markerTintColor = Color.primaryUIColor
80-
8180
if let category = mapItem.pointOfInterestCategory {
8281
switch (category) {
8382
case .airport:
@@ -86,83 +85,17 @@ class SearchResultsMap: NSObject, MapMixin {
8685
annotationView.glyphImage = UIImage(systemName: "hands.sparkles.fill")
8786
case .aquarium:
8887
annotationView.glyphImage = UIImage(systemName: "drop.fill")
89-
case .atm:
90-
annotationView.glyphImage = UIImage(systemName: "dollarsign.circle.fill")
91-
case .bakery:
92-
annotationView.glyphImage = UIImage(systemName: "fork.knife")
93-
case .bank:
88+
case .atm, .bank:
9489
annotationView.glyphImage = UIImage(systemName: "dollarsign.circle.fill")
9590
case .beach:
9691
annotationView.glyphImage = UIImage(systemName: "sun.dust.fill")
97-
case .brewery:
98-
annotationView.glyphImage = UIImage(systemName: "fork.knife")
99-
case .cafe:
100-
annotationView.glyphImage = UIImage(systemName: "fork.knife")
101-
case .campground:
102-
annotationView.glyphImage = UIImage(systemName: "mappin")
103-
case .carRental:
104-
annotationView.glyphImage = UIImage(systemName: "mappin")
105-
case .evCharger:
106-
annotationView.glyphImage = UIImage(systemName: "mappin")
107-
case .fireStation:
108-
annotationView.glyphImage = UIImage(systemName: "mappin")
109-
case .fitnessCenter:
110-
annotationView.glyphImage = UIImage(systemName: "mappin")
111-
case .foodMarket:
92+
case .bakery, .brewery, .cafe, .foodMarket, .restaurant:
11293
annotationView.glyphImage = UIImage(systemName: "fork.knife")
113-
case .gasStation:
114-
annotationView.glyphImage = UIImage(systemName: "mappin")
115-
case .hospital:
116-
annotationView.glyphImage = UIImage(systemName: "mappin")
117-
case .hotel:
118-
annotationView.glyphImage = UIImage(systemName: "mappin")
119-
case .laundry:
120-
annotationView.glyphImage = UIImage(systemName: "mappin")
121-
case .library:
122-
annotationView.glyphImage = UIImage(systemName: "mappin")
123-
case .marina:
124-
annotationView.glyphImage = UIImage(systemName: "mappin")
125-
case .movieTheater:
126-
annotationView.glyphImage = UIImage(systemName: "mappin")
127-
case .museum:
128-
annotationView.glyphImage = UIImage(systemName: "mappin")
129-
case .nationalPark:
130-
annotationView.glyphImage = UIImage(systemName: "mappin")
131-
case .nightlife:
132-
annotationView.glyphImage = UIImage(systemName: "mappin")
133-
case .park:
134-
annotationView.glyphImage = UIImage(systemName: "mappin")
135-
case .parking:
136-
annotationView.glyphImage = UIImage(systemName: "mappin")
137-
case .pharmacy:
138-
annotationView.glyphImage = UIImage(systemName: "mappin")
139-
case .police:
140-
annotationView.glyphImage = UIImage(systemName: "mappin")
141-
case .postOffice:
142-
annotationView.glyphImage = UIImage(systemName: "mappin")
143-
case .publicTransport:
144-
annotationView.glyphImage = UIImage(systemName: "mappin")
145-
case .restaurant:
146-
annotationView.glyphImage = UIImage(systemName: "fork.knife")
147-
case .restroom:
148-
annotationView.glyphImage = UIImage(systemName: "mappin")
149-
case .school:
150-
annotationView.glyphImage = UIImage(systemName: "mappin")
151-
case .stadium:
152-
annotationView.glyphImage = UIImage(systemName: "mappin")
153-
case .store:
154-
annotationView.glyphImage = UIImage(systemName: "mappin")
155-
case .theater:
156-
annotationView.glyphImage = UIImage(systemName: "mappin")
157-
case .university:
158-
annotationView.glyphImage = UIImage(systemName: "mappin")
159-
case .winery:
160-
annotationView.glyphImage = UIImage(systemName: "mappin")
161-
case .zoo:
162-
annotationView.glyphImage = UIImage(systemName: "mappin")
16394
default:
16495
annotationView.glyphImage = UIImage(systemName: "mappin")
16596
}
97+
} else {
98+
annotationView.glyphImage = UIImage(systemName: "mappin")
16699
}
167100
return annotationView
168101
}

Marlin/Marlin/Map/UserTrackingButton.swift

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,28 @@
88
import SwiftUI
99
import MapKit
1010

11-
struct UserTrackingButton: View {
12-
@ObservedObject var locationManager: LocationManager = LocationManager.shared
11+
struct UserTrackingButton<Location>: View where Location: LocationManagerProtocol {
12+
@ObservedObject var locationManager: Location
1313

1414
@State var imageName: String = "location"
15-
@State var appearDisabled: Bool = false
15+
@State var userTrackingModeDescription: String = "none"
16+
var appearDisabled: Bool {
17+
!authorized
18+
}
19+
@State var showingAlert: Bool = false
20+
21+
var authorized: Bool {
22+
locationManager.locationStatus == .authorizedAlways || locationManager.locationStatus == .authorizedWhenInUse
23+
}
1624

1725
@AppStorage("userTrackingMode") var userTrackingMode: Int = Int(MKUserTrackingMode.none.rawValue)
1826
var mapState: MapState?
1927

28+
init(mapState: MapState?, locationManager: Location = LocationManager.shared) {
29+
self.mapState = mapState
30+
self.locationManager = locationManager
31+
}
32+
2033
var body: some View {
2134
Button(action: {
2235
buttonPressed()
@@ -27,45 +40,42 @@ struct UserTrackingButton: View {
2740
.renderingMode(.template)
2841
})
2942
}
43+
.accessibilityElement()
44+
.accessibilityLabel("Tracking \(userTrackingModeDescription)\(authorized ? "" : " Unauthorized")")
3045
.onAppear {
31-
setupTrackingButton(locationAuthorizationStatus: locationManager.locationStatus ?? .notDetermined)
46+
setButtonImage()
3247
mapState?.userTrackingMode = userTrackingMode
3348
}
3449
.onChange(of: locationManager.locationStatus ?? .notDetermined) { newValue in
35-
setupTrackingButton(locationAuthorizationStatus: newValue)
50+
setButtonImage()
3651
}
3752
.onChange(of: mapState?.userTrackingMode) { newValue in
3853
if let mode = newValue {
3954
userTrackingMode = mode
4055
setButtonImage()
4156
}
4257
}
43-
.buttonStyle(MaterialFloatingButtonStyle(type: .secondary, size: .mini))
58+
.buttonStyle(MaterialFloatingButtonStyle(type: .secondary, size: .mini, foregroundColor: appearDisabled ? Color.disabledColor : Color.primaryColorVariant))
59+
.alert(isPresented: $showingAlert) {
60+
Alert(title: Text("Location Services Disabled"),
61+
message: Text("Marlin has been denied access to location services. To show your location on the map, please go into your device settings and enable the Location permission."),
62+
primaryButton: .default(Text("Settings"),
63+
action: {
64+
if let url = NSURL(string: UIApplication.openSettingsURLString) as URL? {
65+
UIApplication.shared.open(url, options: [:], completionHandler: nil)
66+
}
67+
}),
68+
secondaryButton: .cancel())
69+
}
4470
}
4571

4672
func buttonPressed() {
47-
let authorized = locationManager.locationStatus == .authorizedAlways || locationManager.locationStatus == .authorizedWhenInUse
4873
if !authorized {
49-
let alert = UIAlertController(title: "Location Services Disabled", message: "Marlin has been denied access to location services. To show your location on the map, please go into your device settings and enable the Location permission.", preferredStyle: .alert)
50-
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
51-
alert.addAction(UIAlertAction(title: "Settings", style: .default, handler: { action in
52-
if let url = NSURL(string: UIApplication.openSettingsURLString) as URL? {
53-
UIApplication.shared.open(url, options: [:], completionHandler: nil)
54-
}
55-
}))
56-
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true, completion: nil)
57-
return
74+
showingAlert = true
75+
} else {
76+
updateTrackingMode()
77+
setButtonImage()
5878
}
59-
60-
updateTrackingMode()
61-
setButtonImage()
62-
}
63-
64-
func setupTrackingButton(locationAuthorizationStatus: CLAuthorizationStatus) {
65-
let authorized = locationAuthorizationStatus == .authorizedAlways || locationAuthorizationStatus == .authorizedWhenInUse
66-
appearDisabled = !authorized
67-
68-
setButtonImage()
6979
}
7080

7181
func updateTrackingMode() {
@@ -88,12 +98,16 @@ struct UserTrackingButton: View {
8898
switch MKUserTrackingMode(rawValue: userTrackingMode) ?? .none {
8999
case .none:
90100
imageName = "location"
101+
userTrackingModeDescription = "none"
91102
case .follow:
92103
imageName = "location.fill"
104+
userTrackingModeDescription = "follow"
93105
case .followWithHeading:
94106
imageName = "location.north.line.fill"
107+
userTrackingModeDescription = "follow with heading"
95108
@unknown default:
96109
imageName = "location"
110+
userTrackingModeDescription = "none"
97111
}
98112
}
99113
}

Marlin/Marlin/Onboarding/OnboardingView.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ protocol UserNotificationCenter {
1717

1818
extension UNUserNotificationCenter: UserNotificationCenter {}
1919

20-
struct OnboardingView: View {
20+
struct OnboardingView<Location>: View where Location: LocationManagerProtocol {
2121
let WELCOME_TAB = 1
2222
let DISCLAIMER_TAB = 2
2323
let LOCATION_TAB = 3
@@ -92,12 +92,12 @@ struct OnboardingView: View {
9292
@AppStorage("showOnMap\(DifferentialGPSStation.key)") var dgpsIsMapped: Bool = false
9393

9494
@ObservedObject var dataSourceList: DataSourceList
95-
var locationManager: LocationManagerProtocol
95+
var locationManager: Location
9696
var userNotificationCenter: UserNotificationCenter
9797

9898
@State var locationAuthorizationStatus: CLAuthorizationStatus
9999

100-
init(dataSourceList: DataSourceList, locationManager: LocationManagerProtocol = LocationManager.shared, userNotificationCenter: UserNotificationCenter = UNUserNotificationCenter.current()) {
100+
init(dataSourceList: DataSourceList, locationManager: Location = LocationManager.shared, userNotificationCenter: UserNotificationCenter = UNUserNotificationCenter.current()) {
101101
self.dataSourceList = dataSourceList
102102
self.locationManager = locationManager
103103
self.userNotificationCenter = userNotificationCenter

Marlin/Marlin/Views/MSIListView.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ struct MSIListView<T: BatchImportable & DataSourceViewBuilder, Content: View>: V
2626
var watchFocusedItem: Bool = false
2727

2828
let sectionNameBuilder: ((MSISection<T>) -> String)?
29-
// @ViewBuilder let content: any View
3029

3130
let content: ((MSISection<T>) -> Content)?
3231

Marlin/MarlinTests/DataSources/ASAM/ASAMDataTests.swift

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -175,22 +175,16 @@ final class ASAMDataTests: XCTestCase {
175175
return true
176176
}
177177

178-
expectation(forNotification: .NSManagedObjectContextDidSave, object: nil) { notification in
179-
print("xxx notification")
180-
let count = try? self.persistentStore.countOfObjects(Asam.self)
181-
if count != 3 {
182-
let asams = try? self.persistentStore.viewContext.fetchAll(Asam.self)
183-
print("xxxasams are \(asams)")
184-
return false
185-
} else {
186-
print("xxx there were 3")
187-
XCTAssertEqual(count, 3)
188-
return true
178+
let e5 = XCTNSPredicateExpectation(predicate: NSPredicate(block: { observedObject, change in
179+
if let count = try? self.persistentStore.countOfObjects(Asam.self) {
180+
return count == 3
189181
}
190-
}
182+
return false
183+
}), object: self.persistentStore.viewContext)
191184

192185
MSI.shared.loadData(type: Asam.decodableRoot, dataType: Asam.self)
193-
186+
wait(for: [e5], timeout: 10)
187+
194188
waitForExpectations(timeout: 10, handler: nil)
195189

196190
let updatedAsam = try! XCTUnwrap(self.persistentStore.fetchFirst(Asam.self, sortBy: [Asam.defaultSort[0].toNSSortDescriptor()], predicate: NSPredicate(format: "reference = %@", "2022-216")))
@@ -202,7 +196,6 @@ final class ASAMDataTests: XCTestCase {
202196

203197
XCTAssertEqual(newAsam.reference, "2022-218")
204198
XCTAssertEqual(newAsam.asamDescription, "THIS ONE IS NEW")
205-
print("xxx success")
206199
}
207200

208201
func testRejectInvalidAsamNoReference() throws {

0 commit comments

Comments
 (0)