@@ -14,10 +14,10 @@ import AsyncAlgorithms
14
14
import AsyncSequenceValidation
15
15
16
16
extension XCTestCase {
17
- func recordFailure( _ description: String , detail : String ? = nil , system: Bool = false , at location: AsyncSequenceValidation . SourceLocation ) {
17
+ func recordFailure( _ description: String , system: Bool = false , at location: AsyncSequenceValidation . SourceLocation ) {
18
18
#if canImport(Darwin)
19
19
let context = XCTSourceCodeContext ( location: XCTSourceCodeLocation ( filePath: location. file. description, lineNumber: Int ( location. line) ) )
20
- let issue = XCTIssue ( type: system ? . system : . assertionFailure, compactDescription: description, detailedDescription: detail , sourceCodeContext: context, associatedError: nil , attachments: [ ] )
20
+ let issue = XCTIssue ( type: system ? . system : . assertionFailure, compactDescription: description, detailedDescription: nil , sourceCodeContext: context, associatedError: nil , attachments: [ ] )
21
21
record ( issue)
22
22
#else
23
23
XCTFail ( description, file: location. file, line: location. line)
@@ -26,32 +26,36 @@ extension XCTestCase {
26
26
27
27
func validate< Test: AsyncSequenceValidationTest , Theme: AsyncSequenceValidationTheme > ( theme: Theme , expectedFailures: Set < String > , @AsyncSequenceValidationDiagram _ build: ( AsyncSequenceValidationDiagram ) -> Test , file: StaticString = #file, line: UInt = #line) {
28
28
var expectations = expectedFailures
29
+ var result : AsyncSequenceValidationDiagram . ExpectationResult ?
30
+ var failures = [ AsyncSequenceValidationDiagram . ExpectationFailure] ( )
29
31
let baseLoc = AsyncSequenceValidation . SourceLocation ( file: file, line: line)
32
+ var accountedFailures = [ AsyncSequenceValidationDiagram . ExpectationFailure] ( )
30
33
do {
31
- let ( result, failures) = try AsyncSequenceValidationDiagram . test ( theme: theme, build)
32
- var detail : String ?
33
- if failures. count > 0 {
34
- detail = """
35
- Expected
36
- \( result. reconstituteExpected ( theme: theme) )
37
- Actual
38
- \( result. reconstituteActual ( theme: theme) )
39
- """
40
- print ( " Expected " )
41
- print ( result. reconstituteExpected ( theme: theme) )
42
- print ( " Actual " )
43
- print ( result. reconstituteActual ( theme: theme) )
44
- }
34
+ ( result, failures) = try AsyncSequenceValidationDiagram . test ( theme: theme, build)
45
35
for failure in failures {
46
36
if expectations. remove ( failure. description) == nil {
47
- recordFailure ( failure. description, detail: detail, at: failure. specification? . location ?? baseLoc)
37
+ recordFailure ( failure. description, at: failure. specification? . location ?? baseLoc)
38
+ } else {
39
+ accountedFailures. append ( failure)
48
40
}
49
41
}
50
42
} catch {
51
43
if expectations. remove ( " \( error) " ) == nil {
52
44
recordFailure ( " \( error) " , system: true , at: ( error as? SourceFailure ) ? . location ?? baseLoc)
53
45
}
54
46
}
47
+ // If no failures were expected and the result reconstitues to something different
48
+ // than what was expected, dump that out as a failure for easier diagnostics, this
49
+ // likely should be done via attachments but that does not display inline code
50
+ // nicely. Ideally we would want to have this display as a runtime warning but those
51
+ // do not have source line attribution; for now XCTFail is good enough.
52
+ if let result = result, expectedFailures. count == 0 {
53
+ let expected = result. reconstituteExpected ( theme: theme)
54
+ let actual = result. reconstituteActual ( theme: theme)
55
+ if expected != actual {
56
+ XCTFail ( " Validation failure: \n Expected: \n \( expected) \n Actual: \n \( actual) " , file: file, line: line)
57
+ }
58
+ }
55
59
// any remaining expectations are failures that were expected but did not happen
56
60
for expectation in expectations {
57
61
XCTFail ( " Expected failure: \( expectation) did not occur. " , file: file, line: line)
0 commit comments