Skip to content

Commit 25f8ed6

Browse files
authored
Merge pull request #142 from Matejkob/chore/ci-improve-job-independence
Improve CI job independence to prevent cascading failures
2 parents 25bec53 + a20e2c7 commit 25f8ed6

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
name: macOS - ${{ matrix.package }} (Xcode ${{ matrix.xcode }})
2222
runs-on: ${{ matrix.os }}
2323
strategy:
24+
fail-fast: false
2425
matrix:
2526
include:
2627
- os: macos-15
@@ -62,6 +63,7 @@ jobs:
6263
name: Ubuntu - ${{ matrix.package }} (Swift ${{ matrix.swift }})
6364
runs-on: ubuntu-latest
6465
strategy:
66+
fail-fast: false
6567
matrix:
6668
swift:
6769
- '6.0'
@@ -126,7 +128,6 @@ jobs:
126128

127129
code-coverage:
128130
name: Gather Code Coverage
129-
needs: macos
130131
runs-on: macos-15
131132
steps:
132133
- name: Checkout repository

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
/*.swiftinterface
77
/*.xcodeproj
88
xcuserdata/
9+
.claude

CLAUDE.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Swift-Spyable is a Swift macro library that generates spy/mock classes for protocols. It replaces manual test double creation with automated, type-safe spy generation using Swift macros.
8+
9+
## Common Commands
10+
11+
### Building and Testing
12+
- `swift build` - Build the package
13+
- `swift test` - Run all tests
14+
- `swift test -Xswiftc -Xfrontend -Xswiftc -dump-macro-expansions --enable-code-coverage` - Run tests with coverage and macro expansion dumps
15+
- `swift test --filter TestName` - Run specific test
16+
17+
### Code Formatting
18+
- `swift format --recursive --in-place ./Package.swift ./Sources ./Tests ./Examples` - Format all code (automatically done by CI)
19+
20+
### Platform-Specific Testing
21+
- macOS: Use Xcode 15.4+ or 16.2+
22+
- Linux: Requires Swift 5.9+
23+
- Run Examples: `cd Examples && swift test`
24+
25+
## Architecture
26+
27+
The codebase follows a clear separation between public API and implementation:
28+
29+
### Core Structure
30+
- `Sources/Spyable/` - Public API (`@Spyable` macro)
31+
- `Sources/SpyableMacro/` - Macro implementation
32+
- `Macro/SpyableMacro.swift` - Main macro entry point
33+
- `Factories/` - Code generation logic split by concern
34+
- `Extractors/` - Protocol syntax extraction
35+
- `Extensions/` - SwiftSyntax utilities
36+
- `Diagnostics/` - Error handling
37+
38+
### Key Design Patterns
39+
1. **Factory Pattern**: Each aspect of spy generation (methods, properties, call tracking) has its own factory
40+
2. **Visitor Pattern**: Uses SwiftSyntax visitors to traverse and analyze protocol declarations
41+
3. **Builder Pattern**: Constructs spy classes incrementally through multiple factories
42+
43+
### Generated Spy Structure
44+
For a protocol `MyProtocol`, the macro generates `MyProtocolSpy` with:
45+
- `{method}Called` - Bool tracking if method was called
46+
- `{method}CallsCount` - Int counting method calls
47+
- `{method}ReceivedArguments` - Tuple of last received arguments
48+
- `{method}ReceivedInvocations` - Array of all invocations
49+
- `{method}Closure` - Optional closure for stubbing behavior
50+
- `{method}ReturnValue` - Stubbed return value (non-void methods)
51+
- `{method}ThrowableError` - Error to throw (throwing methods)
52+
53+
## Development Workflow
54+
55+
### Adding New Features
56+
1. Identify which factory needs modification or if a new factory is needed
57+
2. Update the factory implementation in `Sources/SpyableMacro/Factories/`
58+
3. Add corresponding tests in `Tests/SpyableMacroTests/`
59+
4. Update `SpyFactory.createSpy()` if adding a new factory
60+
5. Test with Examples project to ensure real-world usage works
61+
62+
### Testing Strategy
63+
- Unit tests use `assertBuildResult` for macro expansion testing
64+
- Each factory has dedicated test files (e.g., `UT_CalledFactory.swift`)
65+
- Integration tests live in the Examples project
66+
- Always test edge cases: generics, async/throws, access levels
67+
68+
### Debugging Macros
69+
1. Use `swift test -Xswiftc -Xfrontend -Xswiftc -dump-macro-expansions` to see generated code
70+
2. Add diagnostic messages in macro implementation using `context.diagnose()`
71+
3. Check `SpyableDiagnostic` for existing error types
72+
73+
## Important Considerations
74+
75+
### Swift Syntax
76+
- The project heavily uses SwiftSyntax for AST manipulation
77+
- When modifying syntax generation, ensure proper formatting and indentation
78+
- Use `DeclSyntax`, `TokenSyntax`, and related types from SwiftSyntax
79+
80+
### Compatibility
81+
- Maintains compatibility with Swift 5.9+
82+
- Must work across macOS, Linux, and iOS platforms
83+
- Windows support is experimental (CI disabled)
84+
85+
### Code Generation Rules
86+
1. Generated code respects the original protocol's access level
87+
2. Property spies include both getter and setter tracking
88+
3. Methods with multiple parameters generate tuple types for arguments
89+
4. Generic constraints are preserved in generated spies
90+
5. Associated types are handled but may require manual implementation
91+
92+
### CI/CD
93+
- GitHub Actions automatically formats code on main branch pushes
94+
- PRs are created for formatting changes
95+
- Matrix testing ensures compatibility across platforms and Swift versions
96+
- Code coverage is tracked via Codecov

0 commit comments

Comments
 (0)