From 1e1023524d0a456b03f06a8f33fc77456c605b9a Mon Sep 17 00:00:00 2001 From: Rachel Brindle Date: Mon, 11 Sep 2023 20:53:15 -0700 Subject: [PATCH] Fix swiftlint errors --- Nimble.xcodeproj/project.pbxproj | 10 ++ Sources/Nimble/AsyncExpression.swift | 1 - Sources/Nimble/DSL.swift | 1 - Sources/Nimble/Utils/AsyncAwait.swift | 138 +----------------- Sources/Nimble/Utils/AsyncTimerSequence.swift | 138 ++++++++++++++++++ .../NimbleTests/AsyncTimerSequenceTest.swift | 22 ++- 6 files changed, 159 insertions(+), 151 deletions(-) create mode 100644 Sources/Nimble/Utils/AsyncTimerSequence.swift diff --git a/Nimble.xcodeproj/project.pbxproj b/Nimble.xcodeproj/project.pbxproj index 703d1a227..56164a620 100644 --- a/Nimble.xcodeproj/project.pbxproj +++ b/Nimble.xcodeproj/project.pbxproj @@ -354,6 +354,10 @@ 891364B029E695F300AD535E /* ObjCAllPassTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DDEFAEB31A93CBE6005CA37A /* ObjCAllPassTest.m */; }; 891364B129E695F300AD535E /* ObjcStringersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */; }; 891364B229E6963C00AD535E /* utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F14FB63194180C5009F2A08 /* utils.swift */; }; + 891A04712AB0164500B46613 /* AsyncTimerSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 891A04702AB0164500B46613 /* AsyncTimerSequence.swift */; }; + 891A04722AB0164500B46613 /* AsyncTimerSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 891A04702AB0164500B46613 /* AsyncTimerSequence.swift */; }; + 891A04732AB0164500B46613 /* AsyncTimerSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 891A04702AB0164500B46613 /* AsyncTimerSequence.swift */; }; + 891A04742AB0164500B46613 /* AsyncTimerSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 891A04702AB0164500B46613 /* AsyncTimerSequence.swift */; }; 892FDF1329D3EA7700523A80 /* AsyncExpression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892FDF1229D3EA7700523A80 /* AsyncExpression.swift */; }; 892FDF1429D3EA7700523A80 /* AsyncExpression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892FDF1229D3EA7700523A80 /* AsyncExpression.swift */; }; 892FDF1529D3EA7700523A80 /* AsyncExpression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892FDF1229D3EA7700523A80 /* AsyncExpression.swift */; }; @@ -796,6 +800,7 @@ 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCSatisfyAnyOfTest.m; sourceTree = ""; }; 857D1848253610A900D8693A /* BeWithin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BeWithin.swift; sourceTree = ""; }; 857D184D2536123F00D8693A /* BeWithinTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BeWithinTest.swift; sourceTree = ""; }; + 891A04702AB0164500B46613 /* AsyncTimerSequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncTimerSequence.swift; sourceTree = ""; }; 892FDF1229D3EA7700523A80 /* AsyncExpression.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncExpression.swift; sourceTree = ""; }; 896962402A5FABD000A7929D /* AsyncAllPass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncAllPass.swift; sourceTree = ""; }; 896962452A5FAD4500A7929D /* AsyncAllPassTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncAllPassTest.swift; sourceTree = ""; }; @@ -1140,6 +1145,7 @@ children = ( 1FD8CD261968AB07008ED995 /* PollAwait.swift */, 89F5E08B290B8D22001F9377 /* AsyncAwait.swift */, + 891A04702AB0164500B46613 /* AsyncTimerSequence.swift */, 1FD8CD271968AB07008ED995 /* SourceLocation.swift */, 1FD8CD281968AB07008ED995 /* Stringers.swift */, AE4BA9AC1C88DDB500B73906 /* Errors.swift */, @@ -1718,6 +1724,7 @@ 896962422A5FABD000A7929D /* AsyncAllPass.swift in Sources */, 1FD8CD381968AB07008ED995 /* Expression.swift in Sources */, 1FD8CD3A1968AB07008ED995 /* FailureMessage.swift in Sources */, + 891A04722AB0164500B46613 /* AsyncTimerSequence.swift in Sources */, CDFB6A4C1F7E082500AD8CC7 /* mach_excServer.c in Sources */, 89EEF5A62A03293100988224 /* AsyncPredicate.swift in Sources */, 472FD1351B9E085700C7B8DA /* HaveCount.swift in Sources */, @@ -1844,6 +1851,7 @@ 899441FA2902EF2700C1FAF9 /* DSL+AsyncAwait.swift in Sources */, 1F5DF1781BDCA0F500C3A531 /* BeAnInstanceOf.swift in Sources */, 1F5DF1771BDCA0F500C3A531 /* BeAKindOf.swift in Sources */, + 891A04732AB0164500B46613 /* AsyncTimerSequence.swift in Sources */, 1F5DF17F1BDCA0F500C3A531 /* BeLessThan.swift in Sources */, 1F5DF17C1BDCA0F500C3A531 /* BeGreaterThan.swift in Sources */, 1F91DD331C74BF61002C309F /* BeVoid.swift in Sources */, @@ -2045,6 +2053,7 @@ 896962412A5FABD000A7929D /* AsyncAllPass.swift in Sources */, CDFB6A251F7E07C700AD8CC7 /* CwlCatchException.m in Sources */, 1FD8CD391968AB07008ED995 /* Expression.swift in Sources */, + 891A04712AB0164500B46613 /* AsyncTimerSequence.swift in Sources */, CDFB6A4B1F7E082500AD8CC7 /* mach_excServer.c in Sources */, 89EEF5A52A03293100988224 /* AsyncPredicate.swift in Sources */, 1FD8CD3B1968AB07008ED995 /* FailureMessage.swift in Sources */, @@ -2171,6 +2180,7 @@ 899441FB2902EF2800C1FAF9 /* DSL+AsyncAwait.swift in Sources */, D95F8968267EA20A004B1B4D /* BeGreaterThan.swift in Sources */, D95F8972267EA20A004B1B4D /* Match.swift in Sources */, + 891A04742AB0164500B46613 /* AsyncTimerSequence.swift in Sources */, D95F8986267EA20E004B1B4D /* Stringers.swift in Sources */, D95F8985267EA20E004B1B4D /* NimbleTimeInterval.swift in Sources */, D95F895A267EA205004B1B4D /* Expression.swift in Sources */, diff --git a/Sources/Nimble/AsyncExpression.swift b/Sources/Nimble/AsyncExpression.swift index e643637c8..59667840e 100644 --- a/Sources/Nimble/AsyncExpression.swift +++ b/Sources/Nimble/AsyncExpression.swift @@ -120,4 +120,3 @@ public struct AsyncExpression { ) } } - diff --git a/Sources/Nimble/DSL.swift b/Sources/Nimble/DSL.swift index 0af089091..d61ac60d5 100644 --- a/Sources/Nimble/DSL.swift +++ b/Sources/Nimble/DSL.swift @@ -111,7 +111,6 @@ internal func internalError(_ msg: String, file: FileString = #file, line: UInt Please file a bug to Nimble: https://github.com/Quick/Nimble/issues with the code snippet that caused this error. """ ) - // swiftlint:enable line_length } #if canImport(Darwin) diff --git a/Sources/Nimble/Utils/AsyncAwait.swift b/Sources/Nimble/Utils/AsyncAwait.swift index f38400fb0..556d54585 100644 --- a/Sources/Nimble/Utils/AsyncAwait.swift +++ b/Sources/Nimble/Utils/AsyncAwait.swift @@ -7,139 +7,6 @@ import Foundation private let timeoutLeeway = NimbleTimeInterval.milliseconds(1) private let pollLeeway = NimbleTimeInterval.milliseconds(1) -// Basically a re-implementation of Clock and InstantProtocol. -// This can be removed once we drop support for iOS < 16. -internal protocol NimbleClockProtocol: Sendable { - associatedtype Instant: NimbleInstantProtocol - - func now() -> Instant - - func sleep(until: Instant) async throws -} - -internal protocol NimbleInstantProtocol: Sendable, Comparable { - associatedtype Interval: NimbleIntervalProtocol - - func advanced(byInterval: Interval) -> Self - - func intervalSince(_: Self) -> Interval -} - -internal protocol NimbleIntervalProtocol: Sendable, Comparable { - static func + (lhs: Self, rhs: Self) -> Self - static func - (lhs: Self, rhs: Self) -> Self - static func * (lhs: Self, rhs: Self) -> Self - static func / (lhs: Self, rhs: Self) -> Self - - func rounded(_ rule: FloatingPointRoundingRule) -> Self -} - -internal struct DateClock: NimbleClockProtocol { - typealias Instant = Date - - func now() -> Instant { - Date() - } - - func sleep(until: Instant) async throws { - try await Task.sleep(nanoseconds: UInt64(Swift.max(0, until.timeIntervalSinceNow * 1_000_000_000))) - } -} - -// Date is Sendable as of at least iOS 16. -// But as of Swift 5.9, it's still not Sendable in the open source version. -extension Date: @unchecked Sendable {} - -extension Date: NimbleInstantProtocol { - typealias Interval = NimbleTimeInterval - - func advanced(byInterval interval: NimbleTimeInterval) -> Date { - advanced(by: interval.timeInterval) - } - - func intervalSince(_ other: Date) -> NimbleTimeInterval { - timeIntervalSince(other).nimbleInterval - } -} - -extension NimbleTimeInterval: NimbleIntervalProtocol { - func rounded(_ rule: FloatingPointRoundingRule) -> NimbleTimeInterval { - timeInterval.rounded(rule).nimbleInterval - } - - static func + (lhs: NimbleTimeInterval, rhs: NimbleTimeInterval) -> NimbleTimeInterval { - (lhs.timeInterval + rhs.timeInterval).nimbleInterval - } - - static func - (lhs: NimbleTimeInterval, rhs: NimbleTimeInterval) -> NimbleTimeInterval { - (lhs.timeInterval - rhs.timeInterval).nimbleInterval - } - - static func * (lhs: NimbleTimeInterval, rhs: NimbleTimeInterval) -> NimbleTimeInterval { - (lhs.timeInterval * rhs.timeInterval).nimbleInterval - } - - static func / (lhs: NimbleTimeInterval, rhs: NimbleTimeInterval) -> NimbleTimeInterval { - (lhs.timeInterval / rhs.timeInterval).nimbleInterval - } - - public static func < (lhs: NimbleTimeInterval, rhs: NimbleTimeInterval) -> Bool { - lhs.timeInterval < rhs.timeInterval - } -} - -// Similar to (made by directly referencing) swift-async-algorithm's AsyncTimerSequence. -// https://github.com/apple/swift-async-algorithms/blob/main/Sources/AsyncAlgorithms/AsyncTimerSequence.swift -// Only this one is compatible with OS versions that Nimble supports. -struct AsyncTimerSequence: AsyncSequence { - typealias Element = Void - let clock: Clock - let interval: Clock.Instant.Interval - - struct AsyncIterator: AsyncIteratorProtocol { - typealias Element = Void - - let clock: Clock - let interval: Clock.Instant.Interval - - var last: Clock.Instant? = nil - - func nextDeadline() -> Clock.Instant { - let now = clock.now() - - let last = self.last ?? now - let next = last.advanced(byInterval: interval) - if next < now { - let nextTimestep = interval * (now.intervalSince(next) / interval).rounded(.up) - return last.advanced(byInterval: nextTimestep) - } else { - return next - } - } - - mutating func next() async -> Void? { - let next = nextDeadline() - do { - try await clock.sleep(until: next) - } catch { - return nil - } - last = next - return () - } - } - - func makeAsyncIterator() -> AsyncIterator { - return AsyncIterator(clock: clock, interval: interval) - } -} - -extension AsyncTimerSequence { - init(interval: NimbleTimeInterval) { - self.init(clock: DateClock(), interval: interval) - } -} - // Like PollResult, except it doesn't support objective-c exceptions. // Which is tolerable because Swift Concurrency doesn't support recording objective-c exceptions. internal enum AsyncPollResult { @@ -177,7 +44,7 @@ internal enum AsyncPollResult { case .incomplete: return .incomplete case .timedOut: return .timedOut case .blockedRunLoop: return .blockedRunLoop - case .completed(let t): return .completed(t) + case .completed(let value): return .completed(value) case .errorThrown(let error): return .errorThrown(error) } } @@ -240,7 +107,7 @@ internal actor AsyncPromise { } } -///.Wait until the timeout period, then checks why the matcher might have timed out +/// Wait until the timeout period, then checks why the matcher might have timed out /// /// Why Dispatch? /// @@ -468,5 +335,4 @@ internal func pollBlock( ) } - #endif // #if !os(WASI) diff --git a/Sources/Nimble/Utils/AsyncTimerSequence.swift b/Sources/Nimble/Utils/AsyncTimerSequence.swift new file mode 100644 index 000000000..6bd46b83c --- /dev/null +++ b/Sources/Nimble/Utils/AsyncTimerSequence.swift @@ -0,0 +1,138 @@ +#if !os(WASI) + +import CoreFoundation +import Dispatch +import Foundation + +// Basically a re-implementation of Clock and InstantProtocol. +// This can be removed once we drop support for iOS < 16. +internal protocol NimbleClockProtocol: Sendable { + associatedtype Instant: NimbleInstantProtocol + + func now() -> Instant + + func sleep(until: Instant) async throws +} + +internal protocol NimbleInstantProtocol: Sendable, Comparable { + associatedtype Interval: NimbleIntervalProtocol + + func advanced(byInterval: Interval) -> Self + + func intervalSince(_: Self) -> Interval +} + +internal protocol NimbleIntervalProtocol: Sendable, Comparable { + static func + (lhs: Self, rhs: Self) -> Self + static func - (lhs: Self, rhs: Self) -> Self + static func * (lhs: Self, rhs: Self) -> Self + static func / (lhs: Self, rhs: Self) -> Self + + func rounded(_ rule: FloatingPointRoundingRule) -> Self +} + +internal struct DateClock: NimbleClockProtocol { + typealias Instant = Date + + func now() -> Instant { + Date() + } + + func sleep(until: Instant) async throws { + try await Task.sleep(nanoseconds: UInt64(Swift.max(0, until.timeIntervalSinceNow * 1_000_000_000))) + } +} + +// Date is Sendable as of at least iOS 16. +// But as of Swift 5.9, it's still not Sendable in the open source version. +extension Date: @unchecked Sendable {} + +extension Date: NimbleInstantProtocol { + typealias Interval = NimbleTimeInterval + + func advanced(byInterval interval: NimbleTimeInterval) -> Date { + advanced(by: interval.timeInterval) + } + + func intervalSince(_ other: Date) -> NimbleTimeInterval { + timeIntervalSince(other).nimbleInterval + } +} + +extension NimbleTimeInterval: NimbleIntervalProtocol { + func rounded(_ rule: FloatingPointRoundingRule) -> NimbleTimeInterval { + timeInterval.rounded(rule).nimbleInterval + } + + static func + (lhs: NimbleTimeInterval, rhs: NimbleTimeInterval) -> NimbleTimeInterval { + (lhs.timeInterval + rhs.timeInterval).nimbleInterval + } + + static func - (lhs: NimbleTimeInterval, rhs: NimbleTimeInterval) -> NimbleTimeInterval { + (lhs.timeInterval - rhs.timeInterval).nimbleInterval + } + + static func * (lhs: NimbleTimeInterval, rhs: NimbleTimeInterval) -> NimbleTimeInterval { + (lhs.timeInterval * rhs.timeInterval).nimbleInterval + } + + static func / (lhs: NimbleTimeInterval, rhs: NimbleTimeInterval) -> NimbleTimeInterval { + (lhs.timeInterval / rhs.timeInterval).nimbleInterval + } + + public static func < (lhs: NimbleTimeInterval, rhs: NimbleTimeInterval) -> Bool { + lhs.timeInterval < rhs.timeInterval + } +} + +// Similar to (made by directly referencing) swift-async-algorithm's AsyncTimerSequence. +// https://github.com/apple/swift-async-algorithms/blob/main/Sources/AsyncAlgorithms/AsyncTimerSequence.swift +// Only this one is compatible with OS versions that Nimble supports. +struct AsyncTimerSequence: AsyncSequence { + typealias Element = Void + let clock: Clock + let interval: Clock.Instant.Interval + + struct AsyncIterator: AsyncIteratorProtocol { + let clock: Clock + let interval: Clock.Instant.Interval + + var last: Clock.Instant? + + func nextDeadline() -> Clock.Instant { + let now = clock.now() + + let last = self.last ?? now + let next = last.advanced(byInterval: interval) + if next < now { + let nextTimestep = interval * (now.intervalSince(next) / interval).rounded(.up) + return last.advanced(byInterval: nextTimestep) + } else { + return next + } + } + + mutating func next() async -> Void? { + let next = nextDeadline() + do { + try await clock.sleep(until: next) + } catch { + return nil + } + last = next + return () + } + } + + func makeAsyncIterator() -> AsyncIterator { + return AsyncIterator(clock: clock, interval: interval) + } +} + +extension AsyncTimerSequence { + init(interval: NimbleTimeInterval) { + self.init(clock: DateClock(), interval: interval) + } +} + +#endif // os(WASI) diff --git a/Tests/NimbleTests/AsyncTimerSequenceTest.swift b/Tests/NimbleTests/AsyncTimerSequenceTest.swift index faf352536..34ebc7046 100644 --- a/Tests/NimbleTests/AsyncTimerSequenceTest.swift +++ b/Tests/NimbleTests/AsyncTimerSequenceTest.swift @@ -13,7 +13,7 @@ final class AsyncTimerSequenceTest: XCTestCase { FakeInstant(now: 1), FakeInstant(now: 2), FakeInstant(now: 3), - FakeInstant(now: 4) + FakeInstant(now: 4), ])) } @@ -27,7 +27,7 @@ final class AsyncTimerSequenceTest: XCTestCase { FakeInstant(now: 2), FakeInstant(now: 4), FakeInstant(now: 6), - FakeInstant(now: 8) + FakeInstant(now: 8), ])) } func testOutputsVoidAtSpecifiedIntervals3() async throws { @@ -40,7 +40,7 @@ final class AsyncTimerSequenceTest: XCTestCase { FakeInstant(now: 3), FakeInstant(now: 6), FakeInstant(now: 9), - FakeInstant(now: 12) + FakeInstant(now: 12), ])) } } @@ -62,20 +62,16 @@ struct FakeClock: NimbleClockProtocol { private final class Implementation: @unchecked Sendable { var _now = FakeInstant(now: 0) var now: FakeInstant { - get { - lock.lock() - defer { lock.unlock() } - return _now - } + lock.lock() + defer { lock.unlock() } + return _now } var _recordedInstants: [FakeInstant] = [FakeInstant(now: 0)] var recordedInstants: [FakeInstant] { - get { - lock.lock() - defer { lock.unlock() } - return _recordedInstants - } + lock.lock() + defer { lock.unlock() } + return _recordedInstants } let lock = NSLock()