Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Swift Testing #39

Merged
merged 11 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ jobs:
run: sudo xcode-select -s /Applications/Xcode_15.4.app
- name: Run ${{ matrix.config }} tests
run: CONFIG=${{ matrix.config }} make test-all
- name: Build for library evolution
run: CONFIG=${{ matrix.config }} make build-for-library-evolution
# - name: Build for library evolution
# run: CONFIG=${{ matrix.config }} make build-for-library-evolution

linux:
strategy:
Expand Down
19 changes: 14 additions & 5 deletions Clocks.xcworkspace/xcshareddata/swiftpm/Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,26 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-plugin",
"state" : {
"revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6",
"revision" : "26ac5758409154cc448d7ab82389c520fa8a8247",
"version" : "1.3.0"
}
},
{
"identity" : "swift-docc-symbolkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-symbolkit",
"state" : {
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
"version" : "1.0.0"
}
},
{
"identity" : "xctest-dynamic-overlay",
"identity" : "swift-issue-reporting",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
"location" : "https://github.com/pointfreeco/swift-issue-reporting",
"state" : {
"revision" : "23cbf2294e350076ea4dbd7d5d047c1e76b03631",
"version" : "1.0.2"
"revision" : "926f43898706eaa127db79ac42138e1ad7e85a3f",
"version" : "1.2.0"
}
}
],
Expand Down
23 changes: 16 additions & 7 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,36 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-concurrency-extras",
"state" : {
"revision" : "ea631ce892687f5432a833312292b80db238186a",
"version" : "1.0.0"
"revision" : "bb5059bde9022d69ac516803f4f227d8ac967f71",
"version" : "1.1.0"
}
},
{
"identity" : "swift-docc-plugin",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-plugin",
"state" : {
"revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6",
"version" : "1.0.0"
"revision" : "26ac5758409154cc448d7ab82389c520fa8a8247",
"version" : "1.3.0"
}
},
{
"identity" : "xctest-dynamic-overlay",
"identity" : "swift-docc-symbolkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
"location" : "https://github.com/apple/swift-docc-symbolkit",
"state" : {
"revision" : "302891700c7fa3b92ebde9fe7b42933f8349f3c7",
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
"version" : "1.0.0"
}
},
{
"identity" : "swift-issue-reporting",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-issue-reporting",
"state" : {
"revision" : "926f43898706eaa127db79ac42138e1ad7e85a3f",
"version" : "1.2.0"
}
}
],
"version" : 2
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
.package(url: "https://github.com/pointfreeco/swift-concurrency-extras", from: "1.0.0"),
.package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.0.0"),
.package(url: "https://github.com/pointfreeco/swift-issue-reporting", from: "1.2.0"),
],
targets: [
.target(
name: "Clocks",
dependencies: [
.product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"),
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
.product(name: "IssueReporting", package: "swift-issue-reporting"),
]
),
.testTarget(
Expand Down
4 changes: 2 additions & 2 deletions Package@swift-6.0.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
.package(url: "https://github.com/pointfreeco/swift-concurrency-extras", from: "1.0.0"),
.package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.0.0"),
.package(url: "https://github.com/pointfreeco/swift-issue-reporting", from: "1.2.0"),
],
targets: [
.target(
name: "Clocks",
dependencies: [
.product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"),
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
.product(name: "IssueReporting", package: "swift-issue-reporting"),
]
),
.testTarget(
Expand Down
16 changes: 10 additions & 6 deletions Sources/Clocks/TestClock.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#if (canImport(RegexBuilder) || !os(macOS) && !targetEnvironment(macCatalyst))
import ConcurrencyExtras
import Foundation
import XCTestDynamicOverlay
import IssueReporting

/// A clock whose time can be controlled in a deterministic manner.
///
Expand Down Expand Up @@ -225,8 +225,10 @@
/// - duration: The amount of time to allow for all work on the clock to finish.
public func run(
timeout duration: Swift.Duration = .milliseconds(500),
file: StaticString = #file,
line: UInt = #line
fileID: StaticString = #fileID,
filePath: StaticString = #filePath,
line: UInt = #line,
column: UInt = #column
) async {
do {
try await withThrowingTaskGroup(of: Void.self) { group in
Expand All @@ -248,7 +250,7 @@
group.cancelAll()
}
} catch {
XCTFail(
reportIssue(
"""
Expected all sleeps to finish, but some are still suspending after \(duration).

Expand All @@ -258,8 +260,10 @@

You can also increase the timeout of 'run' to be greater than \(duration).
""",
file: file,
line: line
fileID: fileID,
filePath: filePath,
line: line,
column: column
)
}
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/Clocks/UnimplementedClock.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#if (canImport(RegexBuilder) || !os(macOS) && !targetEnvironment(macCatalyst))
import ConcurrencyExtras
import Foundation
import XCTestDynamicOverlay
import IssueReporting

/// A clock that causes an XCTest failure when any of its endpoints are invoked.
///
Expand Down Expand Up @@ -101,17 +101,17 @@
}

public var now: Instant {
XCTFail("Unimplemented: \(self.name).now")
reportIssue("Unimplemented: \(self.name).now")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we could pass the proper file-line source context here, but:

  1. We need to pass them into the initializer.
  2. We need to update the .unimplemented static to be a function. While this is technically a breaking change, .unimplemented only recently started working in Swift 6 beta since any Clock did not support it, so it might be an OK breaking change to make.

return Instant(rawValue: self.base.now)
}

public var minimumResolution: Duration {
XCTFail("Unimplemented: \(self.name).minimumResolution")
reportIssue("Unimplemented: \(self.name).minimumResolution")
return self.base.minimumResolution
}

public func sleep(until deadline: Instant, tolerance: Duration?) async throws {
XCTFail("Unimplemented: \(self.name).sleep")
reportIssue("Unimplemented: \(self.name).sleep")
try await self.base.sleep(until: deadline.rawValue, tolerance: tolerance)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/ClocksTests/TestClocksTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ final class TestClockTests: XCTestCase, @unchecked Sendable {
func testRunWithTimeout() async throws {
XCTExpectFailure {
$0.compactDescription == """
Expected all sleeps to finish, but some are still suspending after 1.0 seconds.
failed - Expected all sleeps to finish, but some are still suspending after 1.0 seconds.

There are sleeps suspending. This could mean you are not advancing the test clock far \
enough for your feature to execute its logic, or there could be a bug in your feature's \
Expand Down
16 changes: 8 additions & 8 deletions Tests/ClocksTests/UnimplementedClockTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
func testUnimplementedClock() async throws {
XCTExpectFailure {
[
"Unimplemented: Clock.sleep",
"Unimplemented: Clock.now",
"failed - Unimplemented: Clock.sleep",
"failed - Unimplemented: Clock.now",
]
.contains($0.compactDescription)
}
Expand All @@ -20,8 +20,8 @@
func testUnimplementedClock_WithName() async throws {
XCTExpectFailure {
[
"Unimplemented: ContinuousClock.sleep",
"Unimplemented: ContinuousClock.now",
"failed - Unimplemented: ContinuousClock.sleep",
"failed - Unimplemented: ContinuousClock.now",
]
.contains($0.compactDescription)
}
Expand All @@ -33,8 +33,8 @@
func testNow() async throws {
XCTExpectFailure {
[
"Unimplemented: Clock.sleep",
"Unimplemented: Clock.now",
"failed - Unimplemented: Clock.sleep",
"failed - Unimplemented: Clock.now",
]
.contains($0.compactDescription)
}
Expand All @@ -48,8 +48,8 @@
let task = Task {
XCTExpectFailure {
[
"Unimplemented: Clock.sleep",
"Unimplemented: Clock.now",
"failed - Unimplemented: Clock.sleep",
"failed - Unimplemented: Clock.now",
]
.contains($0.compactDescription)
}
Expand Down