Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
19 changes: 18 additions & 1 deletion Sources/PropertyBased/IssueCounting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,30 @@ func countIssues(isolation: isolated (any Actor)? = #isolation, suppress: Bool,
{
let found = Mutex(0)

// This is currently the only way to get a callback whenever an issue is found within a block.
#if swift(>=6.2)
nonisolated(unsafe) let closure = perform

let handler = IssueHandlingTrait.filterIssues { _ in
found.withLock { $0 += 1 }
return !suppress
}

try? await handler.provideScope(for: Test.current!, testCase: Test.Case.current) {
try await run(closure, in: isolation)
}
#else
try? await withKnownIssue(isIntermittent: true, isolation: isolation) {
try await perform()
} matching: { _ in
found.withLock { $0 += 1 }
return suppress
}
#endif

return found.withLock { $0 }
}

@inlinable
func run(_ closure: () async throws -> Void, in isolation: isolated (any Actor)?) async throws {
try await closure()
}
40 changes: 40 additions & 0 deletions Tests/PropertyBasedTests/ActorTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// ActorTests.swift
// PropertyBased
//
// Created by Lennard Sprong on 08/09/2025.
//

import Testing

@testable import PropertyBased

@globalActor actor OtherActor {
static let shared = OtherActor()

func doNothing() {}
}

@Suite(.shrinking) struct ActorTests {
@MainActor @Test func testOnMainActor() async {
let issues = await countIssues(suppress: true) {
await propertyCheck(input: Gen.int(in: 0...1000)) { i in
await OtherActor.shared.doNothing()
MainActor.assertIsolated("testOnMainActor failure")
#expect(i < 500)
}
}
#expect(issues > 0)
}

@OtherActor @Test func testOnOtherActor() async {
let issues = await countIssues(suppress: true) {
await propertyCheck(input: Gen.int(in: 0...1000)) { i in
await MainActor.run { /* do nothing */ }
OtherActor.assertIsolated("testOnOtherActor failure")
#expect(i < 500)
}
}
#expect(issues > 0)
}
}