diff --git a/CHANGELOG.md b/CHANGELOG.md index d6a6c88..9d9c5ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # DevFoundation Changelog +## 1.7.0: October 27, 2025 + +This is a small release that updates `ExpiringValue` to work better with `DateProvider`. +Specifically, the two initializers spelled `ExpiringValue.init(_:lifetimeDuration:)` have been +updated to include an `any DateProvider` parameter that defaults to `DateProviders.current`. The new +initializers are spelled `ExpiringValue.init(_:dateProvider:lifetimeDuration:)`. + + ## 1.6.0: October 24, 2025 This release introduces the `LiveQuery` subsystem, a set of types for managing search-as-you-type diff --git a/Sources/DevFoundation/Utility Types/ExpiringValue.swift b/Sources/DevFoundation/Utility Types/ExpiringValue.swift index 7cd520c..9e668cd 100644 --- a/Sources/DevFoundation/Utility Types/ExpiringValue.swift +++ b/Sources/DevFoundation/Utility Types/ExpiringValue.swift @@ -38,9 +38,14 @@ public struct ExpiringValue { /// /// - Parameters: /// - value: The value. + /// - dateProvider: The date provider to use to determine the current date. /// - lifetimeDuration: The length of the value’s lifetime. - public init(_ value: Value, lifetimeDuration: Duration) { - let now = DateProviders.current.now + public init( + _ value: Value, + dateProvider: any DateProvider = DateProviders.current, + lifetimeDuration: Duration + ) { + let now = dateProvider.now self.value = value self.lifetimeRange = now ... (now + lifetimeDuration.timeInterval) } @@ -52,9 +57,14 @@ public struct ExpiringValue { /// /// - Parameters: /// - value: The value. + /// - dateProvider: The date provider to use to determine the current date. /// - lifetimeDuration: The length of the value’s lifetime. - public init(_ value: Value, lifetimeDuration: TimeInterval) { - self.init(value, lifetimeDuration: .seconds(lifetimeDuration)) + public init( + _ value: Value, + dateProvider: any DateProvider = DateProviders.current, + lifetimeDuration: TimeInterval + ) { + self.init(value, dateProvider: dateProvider, lifetimeDuration: .seconds(lifetimeDuration)) } diff --git a/Tests/DevFoundationTests/Utility Types/ExpiringValueTests.swift b/Tests/DevFoundationTests/Utility Types/ExpiringValueTests.swift index 1002327..6ef0529 100644 --- a/Tests/DevFoundationTests/Utility Types/ExpiringValueTests.swift +++ b/Tests/DevFoundationTests/Utility Types/ExpiringValueTests.swift @@ -28,17 +28,31 @@ struct ExpiringValueTests: RandomValueGenerating { @Test mutating func durationInitSetsValuesCorrectly() { + let value = randomUUID() + let duration = Duration.milliseconds(randomInt(in: 0 ... 10_000)) + + let now = randomDate() + let dateProvider = MockDateProvider(now: now) + let expiringValue = ExpiringValue(value, dateProvider: dateProvider, lifetimeDuration: duration) + + #expect(expiringValue.value == value) + #expect(expiringValue.lifetimeRange.lowerBound == now) + #expect(expiringValue.lifetimeRange.upperBound == now + duration.timeInterval) + } + + + @Test + mutating func timeIntervalDurationInitSetsValuesCorrectly() { let value = randomUUID() let duration = random(TimeInterval.self, in: 1 ... 10_000) - let date = Date() - let expiringValue = ExpiringValue(value, lifetimeDuration: duration) + let now = randomDate() + let dateProvider = MockDateProvider(now: now) + let expiringValue = ExpiringValue(value, dateProvider: dateProvider, lifetimeDuration: duration) #expect(expiringValue.value == value) - #expect(expiringValue.lifetimeRange.lowerBound.isApproximatelyEqual(to: date, absoluteTolerance: 0.01)) - #expect( - expiringValue.lifetimeRange.upperBound.isApproximatelyEqual(to: date + duration, absoluteTolerance: 0.01) - ) + #expect(expiringValue.lifetimeRange.lowerBound == now) + #expect(expiringValue.lifetimeRange.upperBound == now + duration) }