1+ #if canImport(Darwin)
2+ @preconcurrency import Darwin
3+ #elseif canImport(Glibc)
4+ @preconcurrency import Glibc // disable concurrency safety checks for stdout/stderr flushing
5+ #elseif canImport(CRT)
6+ @preconcurrency import CRT
7+ #endif
8+
9+ // Must be after the Glibc import, because the first occurency of a (transitive) import determines whether
10+ // something is a @preconcurrency import.
11+ import XCTest
12+
13+ // Type names not exported by the proprietary version of XCTest .
14+ #if os(macOS) && !canImport(SwiftXCTest)
15+ private typealias XCTestCaseClosure = ( XCTestCase ) throws -> Void
16+ private typealias XCTestCaseEntry
17+ = ( testCaseClass: XCTestCase . Type , allTests: [ ( String , XCTestCaseClosure ) ] )
18+ #endif
19+
20+ /// The type of `T`'s generated static `allTests` property.
21+ private typealias AllTests < T> = [ ( String , ( T ) -> ( ) throws -> Void ) ]
22+
23+ private extension Array {
24+
25+ /// Transforms `self` into an `XCTestCaseEntry` by erasing `T` from the type and representing
26+ /// it as a string, or returns an empty result if `T` is-not-a `XCTestCase`.
27+ func eraseTestTypes< T> ( ) -> XCTestCaseEntry where Self == AllTests < T > {
28+ guard let t = T . self as? XCTestCase . Type else {
29+ // Skip any methods scraped from non-XCTestCase types.
30+ return ( testCaseClass: XCTestCase . self, allTests: [ ] )
31+ }
32+
33+ func xcTestCaseClosure( _ f: @escaping ( T ) -> ( ) throws -> Void ) -> XCTestCaseClosure {
34+ { ( x: XCTestCase ) throws -> Void in try f ( x as! T ) ( ) }
35+ }
36+
37+ let allTests = self . map { name_f in ( name_f. 0 , xcTestCaseClosure ( name_f. 1 ) ) }
38+ return ( testCaseClass: t, allTests: allTests)
39+ }
40+
41+ }
42+
43+ private extension TestCase {
44+
45+ static var allTests : AllTests < TestCase > {
46+ return [
47+ ( " test1 " , test1) ,
48+ ( " testExtensionMethodsCanBeTests " , testExtensionMethodsCanBeTests) ,
49+ ]
50+ }
51+
52+ }
53+
54+ private extension StructsAreNotTestCases . NestedStructClassesCanBeTestCases {
55+
56+ static var allTests : AllTests < StructsAreNotTestCases . NestedStructClassesCanBeTestCases > {
57+ return [
58+ ( " testNestedClassMethodsCanBeTests " , testNestedClassMethodsCanBeTests) ,
59+ ]
60+ }
61+
62+ }
63+
64+ private extension StructsAreNotTestCases {
65+
66+ static var allTests : AllTests < StructsAreNotTestCases > {
67+ return [
68+ ( " testStructExtensionMethodsAreNotTests " , testStructExtensionMethodsAreNotTests) ,
69+ ]
70+ }
71+
72+ }
73+
74+ private extension EnumsAreNotTestCases . NestedEnumClassesCanBeTestCases {
75+
76+ static var allTests : AllTests < EnumsAreNotTestCases . NestedEnumClassesCanBeTestCases > {
77+ return [
78+ ( " testNestedClassMethodsCanBeTests " , testNestedClassMethodsCanBeTests) ,
79+ ]
80+ }
81+
82+ }
83+
84+ private extension NotAllClassesAreTestCases {
85+
86+ static var allTests : AllTests < NotAllClassesAreTestCases > {
87+ return [
88+ ( " testNonXCTestCaseMethodsAreNotTests " , testNonXCTestCaseMethodsAreNotTests) ,
89+ ]
90+ }
91+
92+ }
93+
94+ /// Feeds `allTestCases` to `XCTMain` if the latter is available.
95+ func runAllTestCases( ) {
96+ /// The full complement of test cases and their individual tests
97+ let allTestCases : [ XCTestCaseEntry ] = [
98+ TestCase . allTests. eraseTestTypes ( ) ,
99+ StructsAreNotTestCases . NestedStructClassesCanBeTestCases. allTests. eraseTestTypes ( ) ,
100+ StructsAreNotTestCases . allTests. eraseTestTypes ( ) ,
101+ EnumsAreNotTestCases . NestedEnumClassesCanBeTestCases. allTests. eraseTestTypes ( ) ,
102+ NotAllClassesAreTestCases . allTests. eraseTestTypes ( )
103+ ]
104+ #if !os(Windows)
105+ // ignore SIGPIPE which is sent when writing to closed file descriptors.
106+ _ = signal ( SIGPIPE, SIG_IGN)
107+ #endif
108+
109+ atexit ( {
110+ fflush ( stdout)
111+ fflush ( stderr)
112+ } )
113+ #if !os(macOS) || canImport(SwiftXCTest)
114+ XCTMain ( allTestCases)
115+ #endif
116+ }
117+ runAllTestCases ( )
0 commit comments