@@ -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,88 @@ 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
146+ var isErrorLevel = rngWithIssues. isError
143147
144- for c in candidates {
145- guard !Task. isCancelled else { return }
148+ var didShrink = EnableShrinkTrait . isEnabled
149+ var shrinkCount = 0
150+ while didShrink {
151+ didShrink = false
152+ let candidates = input. _shrinker ( shrunkenInput)
146153
147- guard let mappedShrunk = input. _mapFilter ( c) else { continue }
154+ for c in candidates {
155+ guard !Task. isCancelled else { return }
148156
149- let shrunkIssues = await countIssues ( isolation: isolation, suppress: true ) {
150- try await body ( mappedShrunk)
151- }
157+ guard let mappedShrunk = input. _mapFilter ( c) else { continue }
152158
153- if shrunkIssues > 0 {
154- didShrink = true
155- shrinkCount += 1
156- shrunkenInput = c
157- break
158- }
159+ let shrunkIssues = await countIssues ( isolation: isolation, suppress: true ) {
160+ try await body ( mappedShrunk)
159161 }
160- }
161162
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) !)
163+ if shrunkIssues. errors > 0 || ( shrunkIssues. warnings > 0 && !isErrorLevel) {
164+ didShrink = true
165+ shrinkCount += 1
166+ shrunkenInput = c
167+ break
166168 }
167169 }
170+ }
171+
172+ // If previous inputs were suppressed, run the block one more time to fully record all issues.
173+ if EnableShrinkTrait . isEnabled {
174+ let finalCount = await countIssues ( isolation: isolation, suppress: false ) {
175+ try await body ( input. _mapFilter ( shrunkenInput) !)
176+ }
177+ if finalCount. errors > 0 {
178+ isErrorLevel = true
179+ }
180+ }
168181
169- let originalParamLabel = String ( describingForTest: resultValue)
182+ let resultValue = input. _mapFilter ( rngWithIssues. value) !
183+ let originalParamLabel = String ( describingForTest: resultValue)
170184
171- let failureMessage : String
185+ let failureMessage : String
172186
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 " : " " ) ) "
187+ let issueTypeLabel = isErrorLevel ? " Failure " : " Warning "
188+
189+ if shrinkCount == 0 {
190+ failureMessage = " \( issueTypeLabel) occured with input \( originalParamLabel) . "
191+ } else {
192+ let shrunkParamLabel = String ( describingForTest: input. _mapFilter ( shrunkenInput) !)
193+ failureMessage =
194+ " \( issueTypeLabel) occured with input \( shrunkParamLabel) . \n (shrunk down from \( originalParamLabel) after \( shrinkCount) iteration \( shrinkCount != 1 ? " s " : " " ) ) "
195+ }
196+
197+ if fixedRng == nil {
198+ if isErrorLevel {
199+ Issue . record (
200+ " \( failureMessage) \n \n Add `.fixedSeed \( seed) ` to the Test to reproduce this issue. " ,
201+ sourceLocation: sourceLocation)
179202 }
180203
181- if fixedRng == nil {
204+ #if swift(>=6.3)
205+ if !isErrorLevel {
182206 Issue . record (
183207 " \( failureMessage) \n \n Add `.fixedSeed \( seed) ` to the Test to reproduce this issue. " ,
208+ severity: . warning,
184209 sourceLocation: sourceLocation)
185- } else {
186- Issue . record ( " \( failureMessage) " , sourceLocation: sourceLocation)
187210 }
188- return
211+ #endif
212+
213+ } else {
214+ Issue . record ( " \( failureMessage) " , sourceLocation: sourceLocation)
189215 }
216+ return
190217 }
191218}
0 commit comments