@@ -20,6 +20,8 @@ private func configurationForEntryPoint(withArguments args: [String]) throws ->
2020
2121private extension Tag {
2222 @Tag static var testTag : Self
23+ @Tag static var testTagOther : Self
24+ @Tag static var unrelatedTag : Self
2325}
2426/// Reads event stream output from the provided file matching event stream
2527/// version `V`.
@@ -184,6 +186,83 @@ struct SwiftPMTests {
184186 #expect( planTests. contains ( test2) )
185187 }
186188
189+ @Test ( " --filter argument with tag: prefix supports regex patterns " )
190+ func filterByTagRegex( ) async throws {
191+ let configuration = try configurationForEntryPoint ( withArguments: [ " PATH " , " --filter " , " tag:testTag.* " ] )
192+ let test1 = Test ( . tags( . testTag) , name: " hello " ) { }
193+ let test2 = Test ( . tags( . testTagOther) , name: " hi " ) { }
194+ let test3 = Test ( . tags( . unrelatedTag) , name: " goodbye " ) { }
195+ let test4 = Test ( name: " untagged " ) { }
196+ let plan = await Runner . Plan ( tests: [ test1, test2, test3, test4] , configuration: configuration)
197+ let planTests = plan. steps. map ( \. test)
198+ #expect( planTests. contains ( test1) )
199+ #expect( planTests. contains ( test2) )
200+ #expect( !planTests. contains ( test3) )
201+ #expect( !planTests. contains ( test4) )
202+ }
203+
204+ @Test ( " --filter tag: argument strips backticks around tag names " )
205+ func filterByTagStripsBackticks( ) async throws {
206+ let configuration = try configurationForEntryPoint ( withArguments: [ " PATH " , " --filter " , " tag:`testTag` " ] )
207+ let test1 = Test ( . tags( . testTag) , name: " hello " ) { }
208+ let test2 = Test ( name: " goodbye " ) { }
209+ let plan = await Runner . Plan ( tests: [ test1, test2] , configuration: configuration)
210+ let planTests = plan. steps. map ( \. test)
211+ #expect( planTests. contains ( test1) )
212+ #expect( !planTests. contains ( test2) )
213+ }
214+
215+ @Test ( " --filter combining tag: and id: patterns AND's them together " )
216+ func mixedPrefixedAndUnprefixedFilters( ) async throws {
217+ let configuration = try configurationForEntryPoint ( withArguments: [ " PATH " , " --filter " , " tag:testTag " , " --filter " , " hello " ] )
218+ let test1 = Test ( . tags( . testTag) , name: " hello " ) { }
219+ let test2 = Test ( . tags( . testTag) , name: " goodbye " ) { }
220+ let test3 = Test ( name: " hello " ) { }
221+ let test4 = Test ( name: " goodbye " ) { }
222+ let plan = await Runner . Plan ( tests: [ test1, test2, test3, test4] , configuration: configuration)
223+ let planTests = plan. steps. map ( \. test)
224+ #expect( planTests. contains ( test1) )
225+ #expect( !planTests. contains ( test2) )
226+ #expect( !planTests. contains ( test3) )
227+ #expect( !planTests. contains ( test4) )
228+ }
229+
230+ @Test ( " --filter argument with explicit id: prefix " )
231+ func filterByExplicitIdPrefix( ) async throws {
232+ let configuration = try configurationForEntryPoint ( withArguments: [ " PATH " , " --filter " , " id:hello " ] )
233+ let test1 = Test ( name: " hello " ) { }
234+ let test2 = Test ( name: " goodbye " ) { }
235+ let plan = await Runner . Plan ( tests: [ test1, test2] , configuration: configuration)
236+ let planTests = plan. steps. map ( \. test)
237+ #expect( planTests. contains ( test1) )
238+ #expect( !planTests. contains ( test2) )
239+ }
240+
241+ @Test ( " --filter tag: combined with --skip id: in the same execution " )
242+ func filterByTagAndSkipById( ) async throws {
243+ let configuration = try configurationForEntryPoint ( withArguments: [ " PATH " , " --filter " , " tag:testTag " , " --skip " , " id:goodbye " ] )
244+ let test1 = Test ( . tags( . testTag) , name: " hello " ) { }
245+ let test2 = Test ( . tags( . testTag) , name: " goodbye " ) { }
246+ let test3 = Test ( . tags( . unrelatedTag) , name: " hello " ) { }
247+ let test4 = Test ( name: " untagged " ) { }
248+ let plan = await Runner . Plan ( tests: [ test1, test2, test3, test4] , configuration: configuration)
249+ let planTests = plan. steps. map ( \. test)
250+ #expect( planTests. contains ( test1) )
251+ #expect( !planTests. contains ( test2) )
252+ #expect( !planTests. contains ( test3) )
253+ #expect( !planTests. contains ( test4) )
254+ }
255+
256+ @Test ( " --filter or --skip tag: argument with bad regex " )
257+ func filterByTagWithBadRegex( ) throws {
258+ #expect( throws: ( any Error ) . self) {
259+ _ = try configurationForEntryPoint ( withArguments: [ " PATH " , " --filter " , " tag:( " ] )
260+ }
261+ #expect( throws: ( any Error ) . self) {
262+ _ = try configurationForEntryPoint ( withArguments: [ " PATH " , " --skip " , " tag:) " ] )
263+ }
264+ }
265+
187266 @Test ( " --filter or --skip argument as last argument " )
188267 func filterOrSkipAsLast( ) async throws {
189268 _ = try configurationForEntryPoint ( withArguments: [ " PATH " , " --filter " ] )
0 commit comments