Repository: Matejkob/swift-spyable (swift)

Issue:
Preprocessor flag can't be retriever when protocol has more then one attribute
**Bug Description:**

When multiple attributes are attached to a protocol, such as `Spyable` and `MainActor`, there is an issue in retrieving `behindPreprocessorFlag` value. 

Consider the following declaration:
```swift
@Spyable(behindPreprocessorFlag: "DEBUG")
protocol Foo {}
```
In this scenario, we can successfully retrieve the value of `behindPreprocessorFlag` because `Spyable` is the only attribute. However, if we add an additional attribute as shown below:
```diff
+@MainActor
@Spyable(behindPreprocessorFlag: "DEBUG")
protocol Foo {}
```
The retrieval of the `Spyable` attribute's value becomes problematic. The current implementation only considers the first attribute attached to the protocol declaration. Therefore, when `Spyable` is not the first attribute, its values become inaccessible.

**Proposed Solution:** 

To resolve this issue, the approach to attribute retrieval needs modification. Instead of only considering the first attribute, the implementation should search the entire list of attributes for the `Spyable` attribute. This can be accomplished by checking for an `attributeName` that matches `Spyable`.

Pull request:
Resolve #79 

Hello 👋
Fix to search for `Spyable` in `AttributeListSyntax` when checking `behindPreprocessorFlag` and add test case.

Patch:
diff --git a/Sources/SpyableMacro/Macro/SpyableMacro.swift b/Sources/SpyableMacro/Macro/SpyableMacro.swift
index e94fdc0..622de9b 100644
--- a/Sources/SpyableMacro/Macro/SpyableMacro.swift
+++ b/Sources/SpyableMacro/Macro/SpyableMacro.swift
@@ -61,7 +61,11 @@ public enum SpyableMacro: PeerMacro {
 extension DeclSyntaxProtocol {
   /// - Returns: The preprocessor `flag` parameter that can be optionally provided via `@Spyable(flag:)`.
   fileprivate var preprocessorFlag: String? {
-    self.as(ProtocolDeclSyntax.self)?.attributes.first?
+    self
+      .as(ProtocolDeclSyntax.self)?.attributes.first {
+        $0.as(AttributeSyntax.self)?.attributeName
+          .as(IdentifierTypeSyntax.self)?.name.text == "Spyable"
+      }?
       .as(AttributeSyntax.self)?.arguments?
       .as(LabeledExprListSyntax.self)?.first {
         $0.label?.text == "behindPreprocessorFlag"


Test patch:
diff --git a/Tests/SpyableMacroTests/Macro/UT_SpyableMacro.swift b/Tests/SpyableMacroTests/Macro/UT_SpyableMacro.swift
index b84fe3c..28187d1 100644
--- a/Tests/SpyableMacroTests/Macro/UT_SpyableMacro.swift
+++ b/Tests/SpyableMacroTests/Macro/UT_SpyableMacro.swift
@@ -207,4 +207,33 @@ final class UT_SpyableMacro: XCTestCase {
       macros: sut
     )
   }
+
+  func testMacroWithFlagMultipleAttributes() {
+    let protocolDeclaration = """
+      public protocol ServiceProtocol {
+          var variable: Bool? { get set }
+      }
+      """
+    assertMacroExpansion(
+      """
+      @MainActor
+      @Spyable(behindPreprocessorFlag: "CUSTOM")
+      @available(*, deprecated)
+      \(protocolDeclaration)
+      """,
+      expandedSource: """
+
+        @MainActor
+        @available(*, deprecated)
+        \(protocolDeclaration)
+
+        #if CUSTOM
+        class ServiceProtocolSpy: ServiceProtocol {
+            var variable: Bool?
+        }
+        #endif
+        """,
+      macros: sut
+    )
+  }
 }