From 76c0860d150033a0c5d6c80b1f5ebea8087de0c3 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 19 Apr 2024 15:27:42 -0400 Subject: [PATCH 01/16] Support member access in tags Currently tags are only recognized when the tag is specified by string literal, i.e: @Tag("foo"). Support Tags added via the staticMember Tag.Kind. --- Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift | 5 ++++- Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift index 84b9e0316..cd7337c57 100644 --- a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift +++ b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift @@ -95,7 +95,10 @@ struct TestingAttributeData { return false } }.flatMap(\.arguments) - .compactMap { $0.expression.as(StringLiteralExprSyntax.self)?.representedLiteralValue } + .compactMap { + $0.expression.as(StringLiteralExprSyntax.self)?.representedLiteralValue ?? + $0.expression.as(MemberAccessExprSyntax.self)?.declName.baseName.text + } self.isDisabled = traitArguments.lazy .compactMap { $0.as(FunctionCallExprSyntax.self) } diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 69162d652..cebc4a05c 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -595,7 +595,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { 1️⃣@Suite(.tags("Suites")) struct MyTests { - 2️⃣@Test(.tags("one", "two")) + 2️⃣@Test(.tags("one", "two", .red, .blue)) func oneIsTwo() { #expect(1 == 2) }3️⃣ @@ -622,7 +622,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { style: TestStyle.swiftTesting, location: Location(uri: uri, range: positions["2️⃣"].. Date: Fri, 19 Apr 2024 17:19:15 -0400 Subject: [PATCH 02/16] Account for nested structs on Tag declarations When a tag is declared within a nested type on Tag include the types name in the tags string representation. --- Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift index cd7337c57..3556058cd 100644 --- a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift +++ b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift @@ -96,8 +96,13 @@ struct TestingAttributeData { } }.flatMap(\.arguments) .compactMap { - $0.expression.as(StringLiteralExprSyntax.self)?.representedLiteralValue ?? - $0.expression.as(MemberAccessExprSyntax.self)?.declName.baseName.text + if let stringLiteral = $0.expression.as(StringLiteralExprSyntax.self) { + return stringLiteral.representedLiteralValue + } else if let memberAccess = $0.expression.as(MemberAccessExprSyntax.self) { + let baseName = (memberAccess.baseName.map { "\($0)." } ?? "").replacing(#/Tag\./#, with: "") + return "\(baseName)\(memberAccess.declName.baseName.text)" + } + return nil } self.isDisabled = traitArguments.lazy From 35fe4aa378e7de2280d43f6d18744aac7320388d Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Sat, 20 Apr 2024 14:37:49 -0400 Subject: [PATCH 03/16] More robust fully qualified name resolution Add a `components` property to MemberAccessExprSyntax that provides all the base names and the member's name as an array. When resolving swift-testing Tags check if they start with Tag or Testing.Tag and drop that from the name. --- .../Swift/SwiftTestingScanner.swift | 57 ++++++++++--------- .../DocumentTestDiscoveryTests.swift | 55 ++++++++++++++++++ 2 files changed, 85 insertions(+), 27 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift index 3556058cd..e33f5e4c9 100644 --- a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift +++ b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift @@ -97,10 +97,15 @@ struct TestingAttributeData { }.flatMap(\.arguments) .compactMap { if let stringLiteral = $0.expression.as(StringLiteralExprSyntax.self) { - return stringLiteral.representedLiteralValue + return stringLiteral.representedLiteralValue } else if let memberAccess = $0.expression.as(MemberAccessExprSyntax.self) { - let baseName = (memberAccess.baseName.map { "\($0)." } ?? "").replacing(#/Tag\./#, with: "") - return "\(baseName)\(memberAccess.declName.baseName.text)" + var components = memberAccess.components[...] + if components.starts(with: ["Testing", "Tag"]) { + components = components.dropFirst(2) + } else if components.starts(with: ["Tag"]) { + components = components.dropFirst(1) + } + return components.joined(separator: ".") } return nil } @@ -336,36 +341,34 @@ fileprivate extension AttributeSyntax { } fileprivate extension MemberAccessExprSyntax { - /// The base name of this instance, i.e. the string value of `base` joined - /// with any preceding base names. + /// The fully-qualified name of this instance (subject to available + /// information.) /// - /// For example, if this instance represents the expression `x.y.z(123)`, - /// the value of this property is `"x.y"`. If the value of `base` is `nil`, - /// the value of this property is also `nil`. - var baseName: String? { - if let declReferenceExpr = base?.as(DeclReferenceExprSyntax.self) { - return declReferenceExpr.baseName.text - } else if let baseMemberAccessExpr = base?.as(MemberAccessExprSyntax.self) { - if let baseBaseName = baseMemberAccessExpr.baseName { - return "\(baseBaseName).\(baseMemberAccessExpr.declName.baseName.text)" - } - return baseMemberAccessExpr.declName.baseName.text - } - - return nil + /// The value of this property are all the components of the based name + /// name joined together with `.`. + var fullyQualifiedName: String { + components.joined(separator: ".") } - /// The fully-qualified name of this instance (subject to available + /// The name components of this instance (subject to available /// information.) /// - /// The value of this property is this instance's `baseName` property joined - /// with its `name` property. For example, if this instance represents the - /// expression `x.y.z(123)`, the value of this property is `"x.y.z"`. - var fullyQualifiedName: String { - if let baseName { - return "\(baseName).\(declName.baseName.text)" + /// The value of this property is this base name of this instance, + /// i.e. the string value of `base` preceeded with any preceding base names + /// and followed by its `name` property. + /// + /// For example, if this instance represents + /// the expression `x.y.z(123)`, the value of this property is + /// `["x", "y", "z"]`. + var components: [String] { + if let declReferenceExpr = base?.as(DeclReferenceExprSyntax.self) { + return [declReferenceExpr.baseName.text, declName.baseName.text] + } else if let baseMemberAccessExpr = base?.as(MemberAccessExprSyntax.self) { + let baseBaseNames = baseMemberAccessExpr.components.dropLast() + return baseBaseNames + [baseMemberAccessExpr.declName.baseName.text, declName.baseName.text] } - return declName.baseName.text + + return [declName.baseName.text] } } diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index cebc4a05c..fe3f3c8bf 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -631,6 +631,61 @@ final class DocumentTestDiscoveryTests: XCTestCase { ) } + func testSwiftTestingTestWithCustomTags() async throws { + let testClient = try await TestSourceKitLSPClient() + let uri = DocumentURI.for(.swift) + + let positions = testClient.openDocument( + """ + import Testing + + extension Tag { + @Tag static var foo: Self + @Tag static var bar: Self + + struct Nested { + @Tag static var foo: Tag + } + } + + 1️⃣@Suite(.tags("Suites")) + struct MyTests { + 2️⃣@Test(.tags(.foo, Nested.foo, Testing.Tag.bar)) + func oneIsTwo() { + #expect(1 == 2) + }3️⃣ + }4️⃣ + """, + uri: uri + ) + + let tests = try await testClient.send(DocumentTestsRequest(textDocument: TextDocumentIdentifier(uri))) + XCTAssertEqual( + tests, + [ + TestItem( + id: "MyTests", + label: "MyTests", + disabled: false, + style: TestStyle.swiftTesting, + location: Location(uri: uri, range: positions["1️⃣"].. Date: Sat, 20 Apr 2024 14:43:42 -0400 Subject: [PATCH 04/16] Add test case for Tag.baz --- Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index fe3f3c8bf..377e9dcec 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -642,6 +642,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { extension Tag { @Tag static var foo: Self @Tag static var bar: Self + @Tag static var baz: Self struct Nested { @Tag static var foo: Tag @@ -650,7 +651,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { 1️⃣@Suite(.tags("Suites")) struct MyTests { - 2️⃣@Test(.tags(.foo, Nested.foo, Testing.Tag.bar)) + 2️⃣@Test(.tags(.foo, Nested.foo, Testing.Tag.bar, Tag.baz)) func oneIsTwo() { #expect(1 == 2) }3️⃣ @@ -677,7 +678,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { style: TestStyle.swiftTesting, location: Location(uri: uri, range: positions["2️⃣"].. Date: Mon, 22 Apr 2024 12:43:43 -0400 Subject: [PATCH 05/16] Break out testSwiftTestingTestWithTags into two tests One that tests string tags, and the other that tests static tags. --- .../DocumentTestDiscoveryTests.swift | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 377e9dcec..221a13e7e 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -585,7 +585,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { ) } - func testSwiftTestingTestWithTags() async throws { + func testSwiftTestingTestWithStringTags() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI.for(.swift) @@ -595,7 +595,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { 1️⃣@Suite(.tags("Suites")) struct MyTests { - 2️⃣@Test(.tags("one", "two", .red, .blue)) + 2️⃣@Test(.tags("one", "two")) func oneIsTwo() { #expect(1 == 2) }3️⃣ @@ -622,7 +622,54 @@ final class DocumentTestDiscoveryTests: XCTestCase { style: TestStyle.swiftTesting, location: Location(uri: uri, range: positions["2️⃣"].. Date: Mon, 22 Apr 2024 15:22:11 -0400 Subject: [PATCH 06/16] Support statically defined tags To remove namespacing ambiguity, support statically defined tags only. --- .../Swift/SwiftTestingScanner.swift | 9 +-- .../DocumentTestDiscoveryTests.swift | 67 ++++--------------- 2 files changed, 18 insertions(+), 58 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift index e33f5e4c9..3155c9437 100644 --- a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift +++ b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift @@ -96,16 +96,17 @@ struct TestingAttributeData { } }.flatMap(\.arguments) .compactMap { - if let stringLiteral = $0.expression.as(StringLiteralExprSyntax.self) { - return stringLiteral.representedLiteralValue - } else if let memberAccess = $0.expression.as(MemberAccessExprSyntax.self) { + if let memberAccess = $0.expression.as(MemberAccessExprSyntax.self) { var components = memberAccess.components[...] if components.starts(with: ["Testing", "Tag"]) { components = components.dropFirst(2) } else if components.starts(with: ["Tag"]) { components = components.dropFirst(1) } - return components.joined(separator: ".") + + // Tags.foo resolves to ".foo", Tags.Nested.foo resolves to "Nested.foo" + let prefix = components.count == 1 ? "." : "" + return "\(prefix)\(components.joined(separator: "."))" } return nil } diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 221a13e7e..73d0af9fb 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -585,7 +585,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { ) } - func testSwiftTestingTestWithStringTags() async throws { + func testSwiftTestingTestWithTags() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI.for(.swift) @@ -593,54 +593,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { """ import Testing - 1️⃣@Suite(.tags("Suites")) - struct MyTests { - 2️⃣@Test(.tags("one", "two")) - func oneIsTwo() { - #expect(1 == 2) - }3️⃣ - }4️⃣ - """, - uri: uri - ) - - let tests = try await testClient.send(DocumentTestsRequest(textDocument: TextDocumentIdentifier(uri))) - XCTAssertEqual( - tests, - [ - TestItem( - id: "MyTests", - label: "MyTests", - disabled: false, - style: TestStyle.swiftTesting, - location: Location(uri: uri, range: positions["1️⃣"].. Date: Mon, 22 Apr 2024 16:03:42 -0400 Subject: [PATCH 07/16] All statics on Tag have a leading . --- Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift | 5 ++--- Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift index 3155c9437..4c923d85f 100644 --- a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift +++ b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift @@ -104,9 +104,8 @@ struct TestingAttributeData { components = components.dropFirst(1) } - // Tags.foo resolves to ".foo", Tags.Nested.foo resolves to "Nested.foo" - let prefix = components.count == 1 ? "." : "" - return "\(prefix)\(components.joined(separator: "."))" + // Tags.foo resolves to ".foo", Tags.Nested.foo resolves to ".Nested.foo" + return ".\(components.joined(separator: "."))" } return nil } diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 73d0af9fb..502d23684 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -681,7 +681,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { children: [], tags: [ TestTag(id: ".foo"), - TestTag(id: "Nested.foo"), + TestTag(id: ".Nested.foo"), TestTag(id: ".bar"), TestTag(id: ".baz") ] From 46286262a1929588500d5a08b825d19d2ab93ba1 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Mon, 22 Apr 2024 16:32:09 -0400 Subject: [PATCH 08/16] Simplify getting MemberAccessExprSyntax.components --- Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift index 4c923d85f..529cd87b9 100644 --- a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift +++ b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift @@ -364,8 +364,7 @@ fileprivate extension MemberAccessExprSyntax { if let declReferenceExpr = base?.as(DeclReferenceExprSyntax.self) { return [declReferenceExpr.baseName.text, declName.baseName.text] } else if let baseMemberAccessExpr = base?.as(MemberAccessExprSyntax.self) { - let baseBaseNames = baseMemberAccessExpr.components.dropLast() - return baseBaseNames + [baseMemberAccessExpr.declName.baseName.text, declName.baseName.text] + return baseMemberAccessExpr.components + [declName.baseName.text] } return [declName.baseName.text] From 3bca8da4feb18a58b578fbfa4da4ea420de75a4a Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 24 Apr 2024 13:49:24 -0400 Subject: [PATCH 09/16] Remove leading dot on string tag representation --- Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift index 529cd87b9..9be38fe1c 100644 --- a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift +++ b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift @@ -103,9 +103,7 @@ struct TestingAttributeData { } else if components.starts(with: ["Tag"]) { components = components.dropFirst(1) } - - // Tags.foo resolves to ".foo", Tags.Nested.foo resolves to ".Nested.foo" - return ".\(components.joined(separator: "."))" + return components.joined(separator: ".") } return nil } From 3b77989ceed5b8ec48045ba2e3bd4a005693b7db Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 24 Apr 2024 13:51:58 -0400 Subject: [PATCH 10/16] Update tag tests --- .../DocumentTestDiscoveryTests.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 502d23684..16fde0587 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -622,10 +622,10 @@ final class DocumentTestDiscoveryTests: XCTestCase { style: TestStyle.swiftTesting, location: Location(uri: uri, range: positions["2️⃣"].. Date: Sat, 20 Apr 2024 14:37:49 -0400 Subject: [PATCH 11/16] More robust fully qualified name resolution Add a `components` property to MemberAccessExprSyntax that provides all the base names and the member's name as an array. When resolving swift-testing Tags check if they start with Tag or Testing.Tag and drop that from the name. --- .../Swift/SwiftTestingScanner.swift | 2 - .../DocumentTestDiscoveryTests.swift | 55 +++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift index 9be38fe1c..9d75ce4b9 100644 --- a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift +++ b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift @@ -364,8 +364,6 @@ fileprivate extension MemberAccessExprSyntax { } else if let baseMemberAccessExpr = base?.as(MemberAccessExprSyntax.self) { return baseMemberAccessExpr.components + [declName.baseName.text] } - - return [declName.baseName.text] } } diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 16fde0587..92e9363ec 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -693,6 +693,61 @@ final class DocumentTestDiscoveryTests: XCTestCase { ) } + func testSwiftTestingTestWithCustomTags() async throws { + let testClient = try await TestSourceKitLSPClient() + let uri = DocumentURI.for(.swift) + + let positions = testClient.openDocument( + """ + import Testing + + extension Tag { + @Tag static var foo: Self + @Tag static var bar: Self + + struct Nested { + @Tag static var foo: Tag + } + } + + 1️⃣@Suite(.tags("Suites")) + struct MyTests { + 2️⃣@Test(.tags(.foo, Nested.foo, Testing.Tag.bar)) + func oneIsTwo() { + #expect(1 == 2) + }3️⃣ + }4️⃣ + """, + uri: uri + ) + + let tests = try await testClient.send(DocumentTestsRequest(textDocument: TextDocumentIdentifier(uri))) + XCTAssertEqual( + tests, + [ + TestItem( + id: "MyTests", + label: "MyTests", + disabled: false, + style: TestStyle.swiftTesting, + location: Location(uri: uri, range: positions["1️⃣"].. Date: Sat, 20 Apr 2024 14:43:42 -0400 Subject: [PATCH 12/16] Add test case for Tag.baz --- Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 92e9363ec..415321546 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -704,6 +704,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { extension Tag { @Tag static var foo: Self @Tag static var bar: Self + @Tag static var baz: Self struct Nested { @Tag static var foo: Tag @@ -712,7 +713,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { 1️⃣@Suite(.tags("Suites")) struct MyTests { - 2️⃣@Test(.tags(.foo, Nested.foo, Testing.Tag.bar)) + 2️⃣@Test(.tags(.foo, Nested.foo, Testing.Tag.bar, Tag.baz)) func oneIsTwo() { #expect(1 == 2) }3️⃣ @@ -739,7 +740,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { style: TestStyle.swiftTesting, location: Location(uri: uri, range: positions["2️⃣"].. Date: Mon, 22 Apr 2024 12:43:43 -0400 Subject: [PATCH 13/16] Break out testSwiftTestingTestWithTags into two tests One that tests string tags, and the other that tests static tags. --- Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 415321546..70ebac1c5 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -585,7 +585,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { ) } - func testSwiftTestingTestWithTags() async throws { + func testSwiftTestingTestWithStringTags() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI.for(.swift) From 6f850ab08477bd84ec1d8b47d3cd2a64607c940b Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 24 Apr 2024 13:51:58 -0400 Subject: [PATCH 14/16] Update tag tests --- .../Swift/SwiftTestingScanner.swift | 1 + .../DocumentTestDiscoveryTests.swift | 58 +------------------ 2 files changed, 2 insertions(+), 57 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift index 9d75ce4b9..66ce7a20d 100644 --- a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift +++ b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift @@ -364,6 +364,7 @@ fileprivate extension MemberAccessExprSyntax { } else if let baseMemberAccessExpr = base?.as(MemberAccessExprSyntax.self) { return baseMemberAccessExpr.components + [declName.baseName.text] } + return [declName.baseName.text] } } diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 70ebac1c5..16fde0587 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -585,7 +585,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { ) } - func testSwiftTestingTestWithStringTags() async throws { + func testSwiftTestingTestWithTags() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI.for(.swift) @@ -693,62 +693,6 @@ final class DocumentTestDiscoveryTests: XCTestCase { ) } - func testSwiftTestingTestWithCustomTags() async throws { - let testClient = try await TestSourceKitLSPClient() - let uri = DocumentURI.for(.swift) - - let positions = testClient.openDocument( - """ - import Testing - - extension Tag { - @Tag static var foo: Self - @Tag static var bar: Self - @Tag static var baz: Self - - struct Nested { - @Tag static var foo: Tag - } - } - - 1️⃣@Suite(.tags("Suites")) - struct MyTests { - 2️⃣@Test(.tags(.foo, Nested.foo, Testing.Tag.bar, Tag.baz)) - func oneIsTwo() { - #expect(1 == 2) - }3️⃣ - }4️⃣ - """, - uri: uri - ) - - let tests = try await testClient.send(DocumentTestsRequest(textDocument: TextDocumentIdentifier(uri))) - XCTAssertEqual( - tests, - [ - TestItem( - id: "MyTests", - label: "MyTests", - disabled: false, - style: TestStyle.swiftTesting, - location: Location(uri: uri, range: positions["1️⃣"].. Date: Wed, 24 Apr 2024 16:49:40 -0400 Subject: [PATCH 15/16] Lint fix --- .../Swift/SwiftTestingScanner.swift | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift index 66ce7a20d..bcb1ced1b 100644 --- a/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift +++ b/Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift @@ -96,16 +96,16 @@ struct TestingAttributeData { } }.flatMap(\.arguments) .compactMap { - if let memberAccess = $0.expression.as(MemberAccessExprSyntax.self) { - var components = memberAccess.components[...] - if components.starts(with: ["Testing", "Tag"]) { - components = components.dropFirst(2) - } else if components.starts(with: ["Tag"]) { - components = components.dropFirst(1) - } - return components.joined(separator: ".") + if let memberAccess = $0.expression.as(MemberAccessExprSyntax.self) { + var components = memberAccess.components[...] + if components.starts(with: ["Testing", "Tag"]) { + components = components.dropFirst(2) + } else if components.starts(with: ["Tag"]) { + components = components.dropFirst(1) } - return nil + return components.joined(separator: ".") + } + return nil } self.isDisabled = traitArguments.lazy From 7015084690fc17aaeb7d663e043a4283043e2844 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Thu, 25 Apr 2024 09:02:20 -0400 Subject: [PATCH 16/16] Lint fix again --- Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 16fde0587..3da0cebc2 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -683,7 +683,7 @@ final class DocumentTestDiscoveryTests: XCTestCase { TestTag(id: "foo"), TestTag(id: "Nested.foo"), TestTag(id: "bar"), - TestTag(id: "baz") + TestTag(id: "baz"), ] ) ],