@@ -115,6 +115,7 @@ public func propertyCheck<InputValue, ResultValue>(
115115 guard count > 0 else { return }
116116
117117 let fixedRng = FixedSeedTrait . fixedRandom
118+ var rngWithIssues : ( rng: Xoshiro , value: InputValue , isError: Bool ) ?
118119
119120 let actualCount = fixedRng != nil ? 1 : count
120121
@@ -130,62 +131,84 @@ public func propertyCheck<InputValue, ResultValue>(
130131 try await body ( resultValue)
131132 }
132133
133- if foundIssues > 0 {
134- let seed = rngCopy. traitHint
134+ if foundIssues. errors > 0 {
135+ rngWithIssues = ( rngCopy, inputValue, isError: true )
136+ break
137+ } else if rngWithIssues == nil , foundIssues. warnings > 0 {
138+ rngWithIssues = ( rngCopy, inputValue, isError: false )
139+ }
140+ }
135141
136- var shrunkenInput = inputValue
142+ if let rngWithIssues {
143+ let seed = rngWithIssues. rng. traitHint
137144
138- var didShrink = EnableShrinkTrait . isEnabled
139- var shrinkCount = 0
140- while didShrink {
141- didShrink = false
142- let candidates = input. _shrinker ( shrunkenInput)
145+ var shrunkenInput = rngWithIssues. value
143146
144- for c in candidates {
145- guard !Task. isCancelled else { return }
147+ var didShrink = EnableShrinkTrait . isEnabled
148+ var shrinkCount = 0
149+ while didShrink {
150+ didShrink = false
151+ let candidates = input. _shrinker ( shrunkenInput)
146152
147- guard let mappedShrunk = input. _mapFilter ( c) else { continue }
153+ for c in candidates {
154+ guard !Task. isCancelled else { return }
148155
149- let shrunkIssues = await countIssues ( isolation: isolation, suppress: true ) {
150- try await body ( mappedShrunk)
151- }
156+ guard let mappedShrunk = input. _mapFilter ( c) else { continue }
152157
153- if shrunkIssues > 0 {
154- didShrink = true
155- shrinkCount += 1
156- shrunkenInput = c
157- break
158- }
158+ let shrunkIssues = await countIssues ( isolation: isolation, suppress: true ) {
159+ try await body ( mappedShrunk)
159160 }
160- }
161161
162- // If previous inputs were suppressed, run the block one more time to fully record all issues.
163- if EnableShrinkTrait . isEnabled {
164- _ = await countIssues ( isolation: isolation, suppress: false ) {
165- try await body ( input. _mapFilter ( shrunkenInput) !)
162+ if shrunkIssues. errors > 0 || ( shrunkIssues. warnings > 0 && !rngWithIssues. isError) {
163+ didShrink = true
164+ shrinkCount += 1
165+ shrunkenInput = c
166+ break
166167 }
167168 }
169+ }
170+
171+ // If previous inputs were suppressed, run the block one more time to fully record all issues.
172+ if EnableShrinkTrait . isEnabled {
173+ _ = await countIssues ( isolation: isolation, suppress: false ) {
174+ try await body ( input. _mapFilter ( shrunkenInput) !)
175+ }
176+ }
168177
169- let originalParamLabel = String ( describingForTest: resultValue)
178+ let resultValue = input. _mapFilter ( rngWithIssues. value) !
179+ let originalParamLabel = String ( describingForTest: resultValue)
170180
171- let failureMessage : String
181+ let failureMessage : String
172182
173- if shrinkCount == 0 {
174- failureMessage = " Failure occured with input \( originalParamLabel) . "
175- } else {
176- let shrunkParamLabel = String ( describingForTest: input. _mapFilter ( shrunkenInput) !)
177- failureMessage =
178- " Failure occured with input \( shrunkParamLabel) . \n (shrunk down from \( originalParamLabel) after \( shrinkCount) iteration \( shrinkCount != 1 ? " s " : " " ) ) "
183+ let issueTypeLabel = rngWithIssues. isError ? " Failure " : " Warning "
184+
185+ if shrinkCount == 0 {
186+ failureMessage = " \( issueTypeLabel) occured with input \( originalParamLabel) . "
187+ } else {
188+ let shrunkParamLabel = String ( describingForTest: input. _mapFilter ( shrunkenInput) !)
189+ failureMessage =
190+ " \( issueTypeLabel) occured with input \( shrunkParamLabel) . \n (shrunk down from \( originalParamLabel) after \( shrinkCount) iteration \( shrinkCount != 1 ? " s " : " " ) ) "
191+ }
192+
193+ if fixedRng == nil {
194+ if rngWithIssues. isError {
195+ Issue . record (
196+ " \( failureMessage) \n \n Add `.fixedSeed \( seed) ` to the Test to reproduce this issue. " ,
197+ sourceLocation: sourceLocation)
179198 }
180199
181- if fixedRng == nil {
200+ #if swift(>=6.3)
201+ if !rngWithIssues. isError {
182202 Issue . record (
183203 " \( failureMessage) \n \n Add `.fixedSeed \( seed) ` to the Test to reproduce this issue. " ,
204+ severity: . warning,
184205 sourceLocation: sourceLocation)
185- } else {
186- Issue . record ( " \( failureMessage) " , sourceLocation: sourceLocation)
187206 }
188- return
207+ #endif
208+
209+ } else {
210+ Issue . record ( " \( failureMessage) " , sourceLocation: sourceLocation)
189211 }
212+ return
190213 }
191214}
0 commit comments