22//
33// This source file is part of the Swift open source project
44//
5- // Copyright (c) 2014-2024 Apple Inc. and the Swift project authors
5+ // Copyright (c) 2014-2025 Apple Inc. and the Swift project authors
66// Licensed under Apache License v2.0 with Runtime Library Exception
77//
88// See http://swift.org/LICENSE.txt for license information
99// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010//
1111//===----------------------------------------------------------------------===//
12+ import Foundation
1213
1314import Basics
1415import Commands
@@ -18,98 +19,215 @@ import PackageModel
1819import SourceControl
1920import _InternalTestSupport
2021import Workspace
21- import XCTest
22+ import Testing
2223
2324import class Basics. AsyncProcess
2425
25- /// Asserts if a directory (recursively) contains a file.
26- private func XCTAssertDirectoryContainsFile( dir: AbsolutePath , filename: String , file: StaticString = #file, line: UInt = #line) {
26+ /// Expects a directory (recursively) contains a file.
27+ fileprivate func expectDirectoryContainsFile(
28+ dir: AbsolutePath ,
29+ filename: String ,
30+ sourceLocation: SourceLocation = #_sourceLocation,
31+ ) {
2732 do {
2833 for entry in try walk ( dir) {
2934 if entry. basename == filename { return }
3035 }
3136 } catch {
32- XCTFail ( " Failed with error \( error) " , file : file , line : line )
37+ Issue . record ( " Failed with error \( error) " , sourceLocation : sourceLocation )
3338 }
34- XCTFail ( " Directory \( dir) does not contain \( file ) " , file : file , line : line )
39+ Issue . record ( " Directory \( dir) does not contain \( filename ) " , sourceLocation : sourceLocation )
3540}
3641
37- final class CFamilyTargetTestCase : XCTestCase {
38- func testCLibraryWithSpaces( ) async throws {
39- try await fixtureXCTest ( name: " CFamilyTargets/CLibraryWithSpaces " ) { fixturePath in
40- await XCTAssertBuilds ( fixturePath, buildSystem: . native)
41- let debugPath = fixturePath. appending ( components: " .build " , try UserToolchain . default. targetTriple. platformBuildPathComponent, " debug " )
42- XCTAssertDirectoryContainsFile ( dir: debugPath, filename: " Bar.c.o " )
43- XCTAssertDirectoryContainsFile ( dir: debugPath, filename: " Foo.c.o " )
42+ @Suite (
43+ . tags(
44+ . TestSize. large,
45+ ) ,
46+ )
47+ struct CFamilyTargetTestCase {
48+ @Test (
49+ . issue( " https://github.com/swiftlang/swift-build/issues/333 " , relationship: . defect) ,
50+ . tags(
51+ . Feature. Command. Build,
52+ ) ,
53+ arguments: getBuildData ( for: SupportedBuildSystemOnAllPlatforms) ,
54+ )
55+ func cLibraryWithSpaces(
56+ data: BuildData ,
57+ ) async throws {
58+ try await withKnownIssue ( isIntermittent: true ) {
59+ try await fixture ( name: " CFamilyTargets/CLibraryWithSpaces " ) { fixturePath in
60+ try await executeSwiftBuild (
61+ fixturePath,
62+ configuration: data. config,
63+ buildSystem: data. buildSystem,
64+ )
65+ if data. buildSystem == . native {
66+ let binPath = try fixturePath. appending ( components: data. buildSystem. binPath ( for: data. config) )
67+ expectDirectoryContainsFile ( dir: binPath, filename: " Bar.c.o " )
68+ expectDirectoryContainsFile ( dir: binPath, filename: " Foo.c.o " )
69+ }
70+ }
71+ } when: {
72+ data. buildSystem == . swiftbuild
4473 }
4574 }
4675
47- func testCUsingCAndSwiftDep( ) async throws {
48- try await fixtureXCTest ( name: " DependencyResolution/External/CUsingCDep " ) { fixturePath in
76+ @Test (
77+ . tags(
78+ . Feature. Command. Build,
79+ ) ,
80+ arguments: getBuildData ( for: SupportedBuildSystemOnAllPlatforms) ,
81+ )
82+ func cUsingCAndSwiftDep(
83+ data: BuildData ,
84+ ) async throws {
85+ try await fixture ( name: " DependencyResolution/External/CUsingCDep " ) { fixturePath in
4986 let packageRoot = fixturePath. appending ( " Bar " )
50- await XCTAssertBuilds ( packageRoot, buildSystem: . native)
51- let debugPath = fixturePath. appending ( components: " Bar " , " .build " , try UserToolchain . default. targetTriple. platformBuildPathComponent, " debug " )
52- XCTAssertDirectoryContainsFile ( dir: debugPath, filename: " Sea.c.o " )
53- XCTAssertDirectoryContainsFile ( dir: debugPath, filename: " Foo.c.o " )
87+ try await executeSwiftBuild (
88+ packageRoot,
89+ configuration: data. config,
90+ buildSystem: data. buildSystem,
91+ )
92+ if data. buildSystem == . native {
93+ let binPath = try packageRoot. appending ( components: data. buildSystem. binPath ( for: data. config) )
94+ expectDirectoryContainsFile ( dir: binPath, filename: " Sea.c.o " )
95+ expectDirectoryContainsFile ( dir: binPath, filename: " Foo.c.o " )
96+ }
5497 let path = try SwiftPM . packagePath ( for: " Foo " , packageRoot: packageRoot)
55- XCTAssertEqual ( try GitRepository ( path: path) . getTags ( ) , [ " 1.2.3 " ] )
98+ let actualTags = try GitRepository ( path: path) . getTags ( )
99+ #expect( actualTags == [ " 1.2.3 " ] )
56100 }
57101 }
58102
59- func testModuleMapGenerationCases( ) async throws {
60- try await fixtureXCTest ( name: " CFamilyTargets/ModuleMapGenerationCases " ) { fixturePath in
61- await XCTAssertBuilds ( fixturePath, buildSystem: . native)
62- let debugPath = fixturePath. appending ( components: " .build " , try UserToolchain . default. targetTriple. platformBuildPathComponent, " debug " )
63- XCTAssertDirectoryContainsFile ( dir: debugPath, filename: " Jaz.c.o " )
64- XCTAssertDirectoryContainsFile ( dir: debugPath, filename: " main.swift.o " )
65- XCTAssertDirectoryContainsFile ( dir: debugPath, filename: " FlatInclude.c.o " )
66- XCTAssertDirectoryContainsFile ( dir: debugPath, filename: " UmbrellaHeader.c.o " )
103+ @Test (
104+ . tags(
105+ . Feature. Command. Build,
106+ ) ,
107+ arguments: getBuildData ( for: SupportedBuildSystemOnAllPlatforms) ,
108+ )
109+ func moduleMapGenerationCases(
110+ data: BuildData ,
111+ ) async throws {
112+ try await fixture ( name: " CFamilyTargets/ModuleMapGenerationCases " ) { fixturePath in
113+ try await executeSwiftBuild (
114+ fixturePath,
115+ configuration: data. config,
116+ buildSystem: data. buildSystem,
117+ )
118+ if data. buildSystem == . native {
119+ let binPath = try fixturePath. appending ( components: data. buildSystem. binPath ( for: data. config) )
120+ expectDirectoryContainsFile ( dir: binPath, filename: " Jaz.c.o " )
121+ expectDirectoryContainsFile ( dir: binPath, filename: " main.swift.o " )
122+ expectDirectoryContainsFile ( dir: binPath, filename: " FlatInclude.c.o " )
123+ expectDirectoryContainsFile ( dir: binPath, filename: " UmbrellaHeader.c.o " )
124+ }
67125 }
68126 }
69-
70- func testNoIncludeDirCheck( ) async throws {
71- try await fixtureXCTest ( name: " CFamilyTargets/CLibraryNoIncludeDir " ) { fixturePath in
72- await XCTAssertAsyncThrowsError (
127+
128+ @Test (
129+ . tags(
130+ . Feature. Command. Build,
131+ ) ,
132+ arguments: getBuildData ( for: SupportedBuildSystemOnAllPlatforms) ,
133+ )
134+ func noIncludeDirCheck(
135+ data: BuildData ,
136+ ) async throws {
137+ try await fixture ( name: " CFamilyTargets/CLibraryNoIncludeDir " ) { fixturePath in
138+ let error = try await #require( throws: ( any Error ) . self) {
73139 try await executeSwiftBuild (
74140 fixturePath,
75- buildSystem: . native,
76- ) ,
77- " This build should throw an error " ,
78- ) { err in
79- // The err.localizedDescription doesn't capture the detailed error string so interpolate
80- let errStr = " \( err) "
81- let missingIncludeDirStr = " \( ModuleError . invalidPublicHeadersDirectory ( " Cfactorial " ) ) "
82- XCTAssert ( errStr. contains ( missingIncludeDirStr) )
141+ configuration: data. config,
142+ buildSystem: data. buildSystem,
143+ )
83144 }
145+
146+ let errString = " \( error) "
147+ let missingIncludeDirStr = " \( ModuleError . invalidPublicHeadersDirectory ( " Cfactorial " ) ) "
148+ #expect( errString. contains ( missingIncludeDirStr) )
84149 }
85150 }
86151
87- func testCanForwardExtraFlagsToClang( ) async throws {
88- // Try building a fixture which needs extra flags to be able to build.
89- try await fixtureXCTest ( name: " CFamilyTargets/CDynamicLookup " ) { fixturePath in
90- await XCTAssertBuilds ( fixturePath, Xld: [ " -undefined " , " dynamic_lookup " ] , buildSystem: . native)
91- let debugPath = fixturePath. appending ( components: " .build " , try UserToolchain . default. targetTriple. platformBuildPathComponent, " debug " )
92- XCTAssertDirectoryContainsFile ( dir: debugPath, filename: " Foo.c.o " )
152+ @Test (
153+ . tags(
154+ . Feature. Command. Build,
155+ ) ,
156+ arguments: getBuildData ( for: SupportedBuildSystemOnAllPlatforms) ,
157+ )
158+ func canForwardExtraFlagsToClang(
159+ data: BuildData ,
160+
161+ ) async throws {
162+ try await fixture ( name: " CFamilyTargets/CDynamicLookup " ) { fixturePath in
163+ try await executeSwiftBuild (
164+ fixturePath,
165+ configuration: data. config,
166+ Xld: [ " -undefined " , " dynamic_lookup " ] ,
167+ buildSystem: data. buildSystem,
168+ )
169+ if data. buildSystem == . native {
170+ let binPath = try fixturePath. appending ( components: data. buildSystem. binPath ( for: data. config) )
171+ expectDirectoryContainsFile ( dir: binPath, filename: " Foo.c.o " )
172+ }
93173 }
94174 }
95175
96- func testObjectiveCPackageWithTestTarget( ) async throws {
97- #if !os(macOS)
98- try XCTSkipIf ( true , " test is only supported on macOS " )
99- #endif
100- try await fixtureXCTest ( name: " CFamilyTargets/ObjCmacOSPackage " ) { fixturePath in
176+ @Test (
177+ . tags(
178+ . Feature. Command. Build,
179+ . Feature. Command. Test,
180+ ) ,
181+ . requireHostOS( . macOS) ,
182+ arguments: getBuildData ( for: SupportedBuildSystemOnAllPlatforms) ,
183+
184+ )
185+ func objectiveCPackageWithTestTarget(
186+ data: BuildData ,
187+
188+ ) async throws {
189+ try await fixture ( name: " CFamilyTargets/ObjCmacOSPackage " ) { fixturePath in
101190 // Build the package.
102- await XCTAssertBuilds ( fixturePath, buildSystem: . native)
103- XCTAssertDirectoryContainsFile ( dir: fixturePath. appending ( components: " .build " , try UserToolchain . default. targetTriple. platformBuildPathComponent, " debug " ) , filename: " HelloWorldExample.m.o " )
191+ try await executeSwiftBuild (
192+ fixturePath,
193+ configuration: data. config,
194+ buildSystem: data. buildSystem,
195+ )
196+ if data. buildSystem == . native {
197+ let binPath = try fixturePath. appending ( components: data. buildSystem. binPath ( for: data. config) )
198+ expectDirectoryContainsFile ( dir: binPath, filename: " HelloWorldExample.m.o " )
199+ expectDirectoryContainsFile ( dir: binPath, filename: " HelloWorldExample.m.o " )
200+ }
104201 // Run swift-test on package.
105- await XCTAssertSwiftTest ( fixturePath, buildSystem: . native)
202+ try await executeSwiftTest (
203+ fixturePath,
204+ configuration: data. config,
205+ buildSystem: data. buildSystem,
206+ )
207+
106208 }
107209 }
108-
109- func testCanBuildRelativeHeaderSearchPaths( ) async throws {
110- try await fixtureXCTest ( name: " CFamilyTargets/CLibraryParentSearchPath " ) { fixturePath in
111- await XCTAssertBuilds ( fixturePath, buildSystem: . native)
112- XCTAssertDirectoryContainsFile ( dir: fixturePath. appending ( components: " .build " , try UserToolchain . default. targetTriple. platformBuildPathComponent, " debug " ) , filename: " HeaderInclude.swiftmodule " )
210+
211+ @Test (
212+ . tags(
213+ . Feature. Command. Build,
214+ ) ,
215+ arguments: getBuildData ( for: SupportedBuildSystemOnAllPlatforms) ,
216+ )
217+ func canBuildRelativeHeaderSearchPaths(
218+ data: BuildData ,
219+
220+ ) async throws {
221+ try await fixture ( name: " CFamilyTargets/CLibraryParentSearchPath " ) { fixturePath in
222+ try await executeSwiftBuild (
223+ fixturePath,
224+ configuration: data. config,
225+ buildSystem: data. buildSystem,
226+ )
227+ if data. buildSystem == . native {
228+ let binPath = try fixturePath. appending ( components: data. buildSystem. binPath ( for: data. config) )
229+ expectDirectoryContainsFile ( dir: binPath, filename: " HeaderInclude.swiftmodule " )
230+ }
113231 }
114232 }
115233}
0 commit comments