generated from StanfordBDHG/SwiftPackageTemplate
-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cb9fcf1
commit d6aef67
Showing
9 changed files
with
126 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// | ||
// This source file is part of the Stanford Spezi open-source project | ||
// | ||
// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) | ||
// | ||
// SPDX-License-Identifier: MIT | ||
// | ||
|
||
|
||
import HealthKit | ||
import SpeziHealthKit | ||
import XCTest | ||
|
||
|
||
@Observable | ||
final class MockQueryResults: HealthKitQueryResults, @unchecked Sendable { // it really isn't sendable, but we also can't mark it as being MainActor-constrained, but since we only ever mutate it from the MainActor, we should (hopefully???) be safe here?? | ||
typealias Sample = HKQuantitySample | ||
typealias Element = HKQuantitySample | ||
typealias Index = [Sample].Index | ||
|
||
let sampleType: SampleType<Sample> | ||
let timeRange: HealthKitQueryTimeRange | ||
var samples: [Sample] | ||
|
||
let queryError: (any Error)? = nil | ||
|
||
init(sampleType: SampleType<Sample>, timeRange: HealthKitQueryTimeRange, samples: [Sample]) { | ||
self.sampleType = sampleType | ||
self.samples = samples | ||
self.timeRange = timeRange | ||
} | ||
|
||
var startIndex: Index { | ||
samples.startIndex | ||
} | ||
|
||
var endIndex: Index { | ||
samples.endIndex | ||
} | ||
|
||
subscript(position: Index) -> HKQuantitySample { | ||
samples[position] | ||
} | ||
} | ||
|
||
|
||
// MARK: Utility things | ||
|
||
|
||
func makeDateProvider( | ||
interval: (component: Calendar.Component, multiple: Int), | ||
starting startDate: DateComponents | ||
) throws -> some (Sequence<Date> & IteratorProtocol<Date>) { | ||
let cal = Calendar.current | ||
let startDate = try XCTUnwrap(cal.date(from: startDate)) | ||
return sequence(first: startDate) { | ||
cal.date(byAdding: interval.component, value: interval.multiple, to: $0) | ||
} | ||
} | ||
|
||
|
||
|
||
extension HKQuantitySample { | ||
convenience init(type: SampleType<HKQuantitySample>, quantity: HKQuantity, date: Date) { | ||
self.init(type: type.hkSampleType, quantity: quantity, start: date, end: date) | ||
} | ||
} | ||
|
||
|
||
extension IteratorProtocol { | ||
mutating func consume(_ count: Int) { | ||
var numConsumed = 0 | ||
while numConsumed < count, let _ = next() { | ||
numConsumed += 1 | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
extension Collection { | ||
public func makeLoopingIterator() -> LoopingCollectionIterator<Self> { | ||
LoopingCollectionIterator(self) | ||
} | ||
} | ||
|
||
|
||
public struct LoopingCollectionIterator<Base: Collection>: IteratorProtocol { | ||
public typealias Element = Base.Element | ||
|
||
/// The collection we want to provide looping iteration over. | ||
private let base: Base | ||
/// The current iteration state, i.e. the index of the next element to be yielded from the iterator. | ||
private var idx: Base.Index | ||
|
||
fileprivate init(_ base: Base) { | ||
self.base = base | ||
self.idx = base.startIndex | ||
} | ||
|
||
public mutating func next() -> Element? { | ||
defer { | ||
base.formIndex(after: &idx) | ||
if idx >= base.endIndex { | ||
idx = base.startIndex | ||
} | ||
} | ||
return base[idx] | ||
} | ||
|
||
/// "Resets" the iterator to the beginning of the collection. | ||
/// The next call to ``LoopingIterator.next()`` will yield the collection's first element. | ||
public mutating func reset() { | ||
idx = base.startIndex | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file modified
BIN
+27.6 KB
(120%)
...Tests/__Snapshots__/SpeziHealthKitTests/testConditionalHealthChartContent.1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+82.2 KB
(180%)
...Tests/__Snapshots__/SpeziHealthKitTests/testConditionalHealthChartContent.2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file modified
BIN
+34.2 KB
(120%)
...hKitTests/__Snapshots__/SpeziHealthKitTests/testMultiEntryHealthChartView.1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+27.6 KB
(120%)
...ealthKitTests/__Snapshots__/SpeziHealthKitTests/testSimpleHealthChartView.1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+38.8 KB
(120%)
...ealthKitTests/__Snapshots__/SpeziHealthKitTests/testSimpleHealthChartView.2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.