Skip to content

Conversation

@bfahey
Copy link

@bfahey bfahey commented Jan 13, 2026

📝 Summary

Protocols with #if/#elseif/#else/#endif blocks now have their members correctly mocked with the conditional compilation structure preserved. This includes support for methods, properties, initializers, and associated types within conditional blocks.

🛠️ Type of Change

  • Bug fix (change that fixes an issue)
  • New feature (change that adds functionality)
  • Breaking change (bug fix or feature that is not backwards compatible)
  • Documentation (DocC, API docs, markdown files, templates, etc.)
  • Testing (new tests, updated tests, etc.)
  • Refactoring or code formatting (no logic changes)
  • Updating dependencies (Swift packages, Homebrew, etc.)
  • CI/CD (change to automated workflows)
  • Chore (other maintenance)

🧪 How Has This Been Tested?

Ran all unit tests.

🔗 Related PRs or Issues

Closes #136

✅ Checklist

  • I have added relevant tests
  • I have verified all tests pass
  • I have formatted my code using SwiftFormat
  • I have updated documentation (if needed)
  • I have added the appropriate label to my PR
  • I have read the contributing guidelines
  • I agree to follow this project's Code of Conduct

@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

❌ Patch coverage is 96.87500% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.35%. Comparing base (ef30af4) to head (835b842).

Files with missing lines Patch % Lines
...MockingMacros/Macros/MockedMacro/MockedMacro.swift 96.87% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #137      +/-   ##
==========================================
+ Coverage   69.76%   73.35%   +3.59%     
==========================================
  Files          73       73              
  Lines        3678     3866     +188     
==========================================
+ Hits         2566     2836     +270     
+ Misses       1112     1030      -82     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bfahey bfahey added the enhancement New feature or request label Jan 13, 2026
@bfahey bfahey changed the title Add IfConfigDeclSyntax support for conditional compilation in protocols Add IfConfigDeclSyntax support for conditional compilation Jan 13, 2026
Copy link
Collaborator

@graycampbell graycampbell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments/suggestions from my first pass through this

@graycampbell graycampbell force-pushed the 136-add-ifconfigdeclsyntax-support branch from a0fc588 to dce8d14 Compare January 15, 2026 16:40
@graycampbell graycampbell changed the base branch from main to formatting/run-swiftformat January 15, 2026 16:41
Comment on lines +151 to +167
var seenNames: Set<String> = []
let uniqueAssociatedTypes = associatedTypeDeclarations.filter { decl in

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var seenNames: Set<String> = []
let uniqueAssociatedTypes = associatedTypeDeclarations.filter { decl in
var seenNames = Set<String>()
let uniqueAssociatedTypes = associatedTypeDeclarations.filter {
seenNames.insert($0.name.text).inserted
}

Q: Does order matter? If not then Set(associatedTypeDeclarations) will work

Copy link
Collaborator

@graycampbell graycampbell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a hole in how all of this is implemented at the moment. See my comment below about the mock's generic parameter constraints.

for associatedTypeDeclaration in uniqueAssociatedTypes {
let genericParameterName = associatedTypeDeclaration.name.trimmed

if let inheritanceClause = associatedTypeDeclaration.inheritanceClause {
Copy link
Collaborator

@graycampbell graycampbell Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's actually an issue with this PR as it stands right now. Right here (the code contained in this if block), is why the above deduplication of the associated types by name doesn't work.

Problem

If you have a protocol like this:

protocol SomeCollection {
  #if DEBUG
  associatedtype Item: Equatable
  #else
  associatedtype Item: Hashable
  #endif
}

This current implementation is going to create this mock:

final class SomeCollectionMock<Item: Equatable>: SomeCollection {}

But that means the mock will only compile properly for DEBUG.

Possible Solution

If there are any associated types inside #if statements, we need to change how we handle the mock’s generic parameter constraints. So for the example above:

protocol SomeCollection {
  #if DEBUG
  associatedtype Item: Equatable
  #else
  associatedtype Item: Hashable
  #endif
}

We shouldn't emit:

final class SomeCollectionMock<Item: Equatable>: SomeCollection {}

We should emit:

final class SomeCollectionMock<Item> {}

#if DEBUG
  extension SomeCollectionMock: SomeCollection where Item: Equatable {}
#else
  extension SomeCollectionMock: SomeCollection where Item: Hashable {}
#endif

Base automatically changed from formatting/run-swiftformat to main January 16, 2026 20:34
bfahey and others added 6 commits January 16, 2026 14:35
Protocols with #if/#elseif/#else/#endif blocks now have their members
correctly mocked with the conditional compilation structure preserved.
This includes support for methods, properties, initializers, and
associated types within conditional blocks.

Closes #136

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…sted conditionals

- Move ifConfig processing inline in mockMemberBlock to match structure of other declaration types
- Add unit tests for OR conditions (#if DEBUG || TESTFLIGHT)
- Add unit tests for nested #if conditionals

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract mockMemberBlockItems helper that works on MemberBlockItemListSyntax
- mockMemberBlock delegates to shared helper
- mockIfConfigDeclaration uses shared helper directly
- Remove mockIfConfigClause entirely (-46 lines)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bfahey and others added 4 commits January 16, 2026 14:35
When a protocol defines the same associated type with different
constraints across #if branches (e.g., Item: Equatable in DEBUG vs
Item: Hashable otherwise), generate a mock class without constraints
plus conditional extensions that conform with the appropriate
constraints for each branch.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@graycampbell graycampbell force-pushed the 136-add-ifconfigdeclsyntax-support branch from 0a1efbf to 835b842 Compare January 16, 2026 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Support Conditional Compilation in Protocol Declarations

4 participants