Skip to content

Fix autoclosure forwarding in generated mock bodies#146

Merged
graycampbell merged 8 commits into
mainfrom
bugfix/#134/auto-closure-forwarding
Jun 26, 2026
Merged

Fix autoclosure forwarding in generated mock bodies#146
graycampbell merged 8 commits into
mainfrom
bugfix/#134/auto-closure-forwarding

Conversation

@graycampbell

@graycampbell graycampbell commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

📝 Summary

When a mocked protocol method has an @autoclosure parameter, the generated mock body previously passed the closure directly to recordInput and the invoke closure. This caused a compile error: "Add () to forward @autoclosure parameter". The fix evaluates the autoclosure into a local let binding before use, wrapping the call in try and/or await as required by the closure's effect specifiers.

Also renames isInoutParameterisInout and isConsumingParameterisConsuming in MockedMethodMacro+BodyMacro.swift to better follow Swift API Design Guidelines (omit needless words — the Parameter suffix was redundant given the argument label).

compilationCondition: .none is added to every @Mocked usage in MockingClient. Without it, the default .swiftMockingEnabled condition wraps each generated mock in #if SWIFT_MOCKING_ENABLED, so the mock bodies are never compiled during a regular swift build — defeating the purpose of the client as a compilation verification target.

🛠️ 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?

Eight macro expansion tests in MockedMethod_AutoClosureTests, covering all four effect-specifier variants × two autoclosure return type variants (void and non-void):

Test Autoclosure type Method effects
autoClosureWithVoidReturnType () -> Void
autoClosureWithNonVoidReturnType () -> Int
asyncAutoClosureWithVoidReturnType () async -> Void async
asyncAutoClosureWithNonVoidReturnType () async -> Int async
throwingAutoClosureWithVoidReturnType () throws -> Void throws
throwingAutoClosureWithNonVoidReturnType () throws -> Int throws
asyncThrowingAutoClosureWithVoidReturnType () async throws -> Void async throws
asyncThrowingAutoClosureWithNonVoidReturnType () async throws -> Int async throws

Each test verifies the correct let autoClosure = [try] [await] autoClosure() binding is generated, the appropriate effect specifiers appear on the invoke call, and the peer type (MockVoidParameterized[Async][Throwing]Method) and closure type are correct.

AutoClosures.swift in MockingClient is updated with all eight corresponding methods, serving as an end-to-end compilation check.

🔗 Related PRs or Issues

Fixes #134

✅ 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

@graycampbell graycampbell added the bug Something isn't working label Jun 25, 2026
@graycampbell graycampbell self-assigned this Jun 25, 2026
@graycampbell graycampbell changed the title [#134] Fix @autoclosure forwarding in generated mock bodies Fix autoclosure forwarding in generated mock bodies Jun 25, 2026
Add try/await wrapping when calling autoclosure parameters, rename
isInoutParameter/isConsumingParameter to isInout/isConsuming per
API Design Guidelines, and fix AutoClosures.swift client verification.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@graycampbell graycampbell force-pushed the bugfix/#134/auto-closure-forwarding branch from 9afc588 to 77491dd Compare June 25, 2026 15:25
graycampbell and others added 3 commits June 25, 2026 11:17
Add async, throwing, and async-throwing variants of the void and
non-void autoclosure tests, and update AutoClosures.swift with all
eight corresponding methods. Tests and methods are ordered: regular,
async, throwing, async-throwing; with void and non-void autoclosure
return type variants within each group.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Use 4-space indentation for enum body members to match BasicFormat
output; tabs are only present on explicitly-set generic parameter trivia.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@graycampbell graycampbell marked this pull request as ready for review June 25, 2026 20:33
@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.24324% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.12%. Comparing base (6e676a2) to head (fb057ea).

Files with missing lines Patch % Lines
...ockedMethodMacro/MockedMethodMacro+BodyMacro.swift 92.30% 4 Missing ⚠️
...kedMethodMacro/MockedMethodMacro+TypeErasure.swift 95.23% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #146      +/-   ##
==========================================
+ Coverage   78.42%   80.12%   +1.69%     
==========================================
  Files          73       73              
  Lines        4055     4120      +65     
==========================================
+ Hits         3180     3301     +121     
+ Misses        875      819      -56     

☔ View full report in Codecov by Harness.
📢 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.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Without compilationCondition: .none, generated mocks are wrapped in
#if SWIFT_MOCKING_ENABLED and not compiled during a regular build,
defeating the purpose of the client as a compilation verification target.

Co-Authored-By: Claude Code <noreply@anthropic.com>
/// Mocked's handling of attributed types. For temporary testing of Mocked's
/// expansion, use the `Playground` protocol in `main.swift`.
@Mocked
@Mocked(compilationCondition: .none)

@graycampbell graycampbell Jun 25, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

compilationCondition: .none needs to be added to every @Mocked usage in MockingClient. Without it, the default .swiftMockingEnabled condition wraps each generated mock in #if SWIFT_MOCKING_ENABLED, so the mock bodies are never compiled during a regular swift build, defeating the purpose of the client as compilation verification.

@graycampbell graycampbell merged commit 18d77e8 into main Jun 26, 2026
8 checks passed
@graycampbell graycampbell deleted the bugfix/#134/auto-closure-forwarding branch June 26, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Auto-closures are not forwarded correctly

3 participants