@@ -82,6 +82,62 @@ final class APIDiffTests: XCTestCase {
82
82
#endif
83
83
}
84
84
85
+ func testBreakageAllowlist( ) throws {
86
+ #if os(macOS)
87
+ guard ( try ? Resources . default. toolchain. getSwiftAPIDigester ( ) ) != nil else {
88
+ throw XCTSkip ( " swift-api-digester not available " )
89
+ }
90
+ fixture ( name: " Miscellaneous/APIDiff/ " ) { prefix in
91
+ let packageRoot = prefix. appending ( component: " Bar " )
92
+ try localFileSystem. writeFileContents ( packageRoot. appending ( components: " Sources " , " Baz " , " Baz.swift " ) ) {
93
+ $0 <<< " public func baz() -> String { \" hello, world! \" } "
94
+ }
95
+ try localFileSystem. writeFileContents ( packageRoot. appending ( components: " Sources " , " Qux " , " Qux.swift " ) ) {
96
+ $0 <<< " public class Qux<T, U> { private let x = 1 } "
97
+ }
98
+ try localFileSystem. writeFileContents ( packageRoot. appending ( components: " api-breakage-allowlist.txt " ) ) {
99
+ $0 <<< " API breakage: class Qux has generic signature change from <T> to <T, U> \n "
100
+ $0 <<< " API breakage: func bar() has been removed \n "
101
+ }
102
+ let customAllowlistPath = packageRoot. appending ( components: " foo " , " allowlist.txt " )
103
+ try localFileSystem. writeFileContents ( customAllowlistPath) {
104
+ $0 <<< " API breakage: class Qux has generic signature change from <T> to <T, U> \n "
105
+ }
106
+ try localFileSystem. writeFileContents ( packageRoot. appending ( components: " api-breakage-allowlist.txt " ) ) {
107
+ $0 <<< " API breakage: class Qux has generic signature change from <T> to <T, U> \n "
108
+ $0 <<< " API breakage: func bar() has been removed \n "
109
+ }
110
+ XCTAssertThrowsError ( try execute ( [ " experimental-api-diff " , " 1.2.3 " , " -j " , " 2 " ] , packagePath: packageRoot) ) { error in
111
+ guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
112
+ XCTFail ( " Unexpected error " )
113
+ return
114
+ }
115
+ XCTAssertTrue ( output. contains ( " 1 breaking change detected in Qux " ) )
116
+ XCTAssertFalse ( output. contains ( " 💔 API breakage: class Qux has generic signature change from <T> to <T, U> " ) )
117
+ XCTAssertTrue ( output. contains ( " 💔 API breakage: var Qux.x has been removed " ) )
118
+ XCTAssertTrue ( output. contains ( " No breaking changes detected in Baz " ) )
119
+ XCTAssertFalse ( output. contains ( " 💔 API breakage: func bar() has been removed " ) )
120
+ }
121
+ XCTAssertThrowsError ( try execute ( [ " experimental-api-diff " , " 1.2.3 " , " -j " , " 2 " ,
122
+ " --breakage-allowlist-path " , customAllowlistPath. pathString] ,
123
+ packagePath: packageRoot) ) { error in
124
+ guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
125
+ XCTFail ( " Unexpected error " )
126
+ return
127
+ }
128
+ XCTAssertTrue ( output. contains ( " 1 breaking change detected in Qux " ) )
129
+ XCTAssertFalse ( output. contains ( " 💔 API breakage: class Qux has generic signature change from <T> to <T, U> " ) )
130
+ XCTAssertTrue ( output. contains ( " 💔 API breakage: var Qux.x has been removed " ) )
131
+ XCTAssertTrue ( output. contains ( " 1 breaking change detected in Baz " ) )
132
+ XCTAssertTrue ( output. contains ( " 💔 API breakage: func bar() has been removed " ) )
133
+ }
134
+
135
+ }
136
+ #else
137
+ throw XCTSkip ( " Test unsupported on current platform " )
138
+ #endif
139
+ }
140
+
85
141
func testCheckVendedModulesOnly( ) throws {
86
142
#if os(macOS)
87
143
guard ( try ? Resources . default. toolchain. getSwiftAPIDigester ( ) ) != nil else {
0 commit comments