Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4963a23

Browse files
committedMay 30, 2024·
fix: excluding private modifiers for mock members
1 parent f931faa commit 4963a23

File tree

7 files changed

+161
-16
lines changed

7 files changed

+161
-16
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by Nayanda Haberty on 29/5/24.
6+
//
7+
import SwiftSyntax
8+
9+
extension DeclModifierListSyntax {
10+
var excludingPrivateModifiers: DeclModifierListSyntax {
11+
filter { modifier in
12+
guard case .keyword(let keyword) = modifier.name.tokenKind else {
13+
return true
14+
}
15+
return keyword != .private
16+
}
17+
}
18+
}

‎Sources/MockableMacro/Factory/BuilderFactory.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ extension BuilderFactory {
2929
_ requirements: Requirements
3030
) throws -> some DeclSyntaxProtocol {
3131
StructDeclSyntax(
32-
modifiers: requirements.syntax.modifiers,
32+
modifiers: requirements.membersModifiers,
3333
name: kind.name,
3434
inheritanceClause: InheritanceClauseSyntax(inheritedTypes: inheritedTypes(kind)),
3535
memberBlock: MemberBlockSyntax(members: try members(kind, requirements))
@@ -53,7 +53,7 @@ extension BuilderFactory {
5353
MemberBlockItemSyntax(
5454
decl: try variable.builder(
5555
of: kind,
56-
with: requirements.syntax.modifiers,
56+
with: requirements.membersModifiers,
5757
using: requirements.syntax.mockType
5858
)
5959
)
@@ -62,7 +62,7 @@ extension BuilderFactory {
6262
MemberBlockItemSyntax(
6363
decl: try function.builder(
6464
of: kind,
65-
with: requirements.syntax.modifiers,
65+
with: requirements.membersModifiers,
6666
using: requirements.syntax.mockType
6767
)
6868
)
@@ -101,7 +101,7 @@ extension BuilderFactory {
101101
_ requirements: Requirements
102102
) -> InitializerDeclSyntax {
103103
InitializerDeclSyntax(
104-
modifiers: requirements.syntax.modifiers,
104+
modifiers: requirements.membersModifiers,
105105
signature: initializerSignature(kind, requirements)
106106
) {
107107
InfixOperatorExprSyntax(

‎Sources/MockableMacro/Factory/ConformanceFactory.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extension ConformanceFactory {
2727
try MemberBlockItemListSyntax {
2828
for variable in requirements.variables {
2929
MemberBlockItemSyntax(
30-
decl: try variable.implement(with: requirements.syntax.modifiers)
30+
decl: try variable.implement(with: requirements.membersModifiers)
3131
)
3232
}
3333
}
@@ -37,7 +37,7 @@ extension ConformanceFactory {
3737
try MemberBlockItemListSyntax {
3838
for function in requirements.functions {
3939
MemberBlockItemSyntax(
40-
decl: try function.implement(with: requirements.syntax.modifiers)
40+
decl: try function.implement(with: requirements.membersModifiers)
4141
)
4242
}
4343
}
@@ -47,7 +47,7 @@ extension ConformanceFactory {
4747
try MemberBlockItemListSyntax {
4848
for initializer in requirements.initializers {
4949
MemberBlockItemSyntax(
50-
decl: try initializer.implement(with: requirements.syntax.modifiers)
50+
decl: try initializer.implement(with: requirements.membersModifiers)
5151
)
5252
}
5353
}

‎Sources/MockableMacro/Factory/EnumFactory.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import SwiftSyntax
1414
enum EnumFactory: Factory {
1515
static func build(from requirements: Requirements) throws -> EnumDeclSyntax {
1616
EnumDeclSyntax(
17-
modifiers: requirements.syntax.modifiers,
17+
modifiers: requirements.membersModifiers,
1818
name: NS.Member,
1919
inheritanceClause: inheritanceClause,
2020
memberBlock: MemberBlockSyntax(members: try members(requirements))
@@ -67,7 +67,7 @@ extension EnumFactory {
6767
try matcherSwitch(requirements)
6868
}
6969
let decl = FunctionDeclSyntax(
70-
modifiers: requirements.syntax.modifiers,
70+
modifiers: requirements.membersModifiers,
7171
name: NS.match,
7272
signature: signature,
7373
body: .init(statements: statement)

‎Sources/MockableMacro/Factory/MemberFactory.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ enum MemberFactory: Factory {
2929
extension MemberFactory {
3030
private static func defaultInit(_ requirements: Requirements) -> InitializerDeclSyntax {
3131
InitializerDeclSyntax(
32-
modifiers: requirements.syntax.modifiers.trimmed,
32+
modifiers: requirements.membersModifiers,
3333
signature: .init(parameterClause: defaultInitParameters),
3434
body: .init { CodeBlockItemSyntax(item: .expr(mockerAssignmentWithPolicy)) }
3535
)
@@ -64,7 +64,7 @@ extension MemberFactory {
6464
private static func given(_ requirements: Requirements) -> FunctionDeclSyntax {
6565
FunctionDeclSyntax(
6666
attributes: unavailableAttribute(message: Messages.givenMessage),
67-
modifiers: requirements.syntax.modifiers,
67+
modifiers: requirements.membersModifiers,
6868
name: NS.given,
6969
signature: .init(
7070
parameterClause: FunctionParameterClauseSyntax(parameters: []),
@@ -78,7 +78,7 @@ extension MemberFactory {
7878
private static func when(_ requirements: Requirements) -> FunctionDeclSyntax {
7979
FunctionDeclSyntax(
8080
attributes: unavailableAttribute(message: Messages.whenMessage),
81-
modifiers: requirements.syntax.modifiers,
81+
modifiers: requirements.membersModifiers,
8282
name: NS.when,
8383
signature: .init(
8484
parameterClause: FunctionParameterClauseSyntax(parameters: []),
@@ -92,7 +92,7 @@ extension MemberFactory {
9292
private static func verify(_ requirements: Requirements) -> FunctionDeclSyntax {
9393
FunctionDeclSyntax(
9494
attributes: unavailableAttribute(message: Messages.verifyMessage),
95-
modifiers: requirements.syntax.modifiers,
95+
modifiers: requirements.membersModifiers,
9696
name: NS.verify,
9797
signature: .init(
9898
parameterClause: FunctionParameterClauseSyntax(
@@ -110,7 +110,7 @@ extension MemberFactory {
110110
}
111111
private static func reset(_ requirements: Requirements) -> FunctionDeclSyntax {
112112
FunctionDeclSyntax(
113-
modifiers: requirements.syntax.modifiers,
113+
modifiers: requirements.membersModifiers,
114114
name: NS.reset,
115115
signature: .init(
116116
parameterClause: FunctionParameterClauseSyntax(

‎Sources/MockableMacro/Requirements/Requirements.swift

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ struct Requirements {
1111

1212
// MARK: Properties
1313

14-
var syntax: ProtocolDeclSyntax
14+
let syntax: ProtocolDeclSyntax
15+
let membersModifiers: DeclModifierListSyntax
1516
var functions = [FunctionRequirement]()
1617
var variables = [VariableRequirement]()
1718
var initializers = [InitializerRequirement]()
@@ -20,7 +21,7 @@ struct Requirements {
2021

2122
init(_ syntax: ProtocolDeclSyntax) throws {
2223
self.syntax = syntax
23-
24+
self.membersModifiers = syntax.modifiers.trimmed.excludingPrivateModifiers
2425
let members = syntax.memberBlock.members
2526

2627
guard members.compactMap({ $0.decl.as(SubscriptDeclSyntax.self) }).isEmpty else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by Nayanda Haberty on 29/5/24.
6+
//
7+
8+
import MacroTesting
9+
import XCTest
10+
import SwiftSyntax
11+
@testable import Mockable
12+
13+
final class AccessModifierTests: MockableMacroTestCase {
14+
func test_private_access_modifier() {
15+
assertMacro {
16+
"""
17+
@Mockable
18+
private protocol Test {
19+
var foo: Int { get }
20+
func bar(number: Int) -> Int
21+
}
22+
"""
23+
} expansion: {
24+
"""
25+
private protocol Test {
26+
var foo: Int { get }
27+
func bar(number: Int) -> Int
28+
}
29+
30+
#if MOCKING
31+
private final class MockTest: Test, MockService {
32+
private var mocker = Mocker<MockTest>()
33+
@available(*, deprecated, message: "Use given(_ service:) of Mockable instead. ")
34+
func given() -> ReturnBuilder {
35+
.init(mocker: mocker)
36+
}
37+
@available(*, deprecated, message: "Use when(_ service:) of Mockable instead. ")
38+
func when() -> ActionBuilder {
39+
.init(mocker: mocker)
40+
}
41+
@available(*, deprecated, message: "Use verify(_ service:) of MockableTest instead. ")
42+
func verify(with assertion: @escaping MockableAssertion) -> VerifyBuilder {
43+
.init(mocker: mocker, assertion: assertion)
44+
}
45+
func reset(_ scopes: Set<MockerScope> = .all) {
46+
mocker.reset(scopes: scopes)
47+
}
48+
init(policy: MockerPolicy? = nil) {
49+
if let policy {
50+
mocker.policy = policy
51+
}
52+
}
53+
func bar(number: Int) -> Int {
54+
let member: Member = .m2_bar(number: .value(number))
55+
return mocker.mock(member) { producer in
56+
let producer = try cast(producer) as (Int) -> Int
57+
return producer(number)
58+
}
59+
}
60+
var foo: Int {
61+
get {
62+
let member: Member = .m1_foo
63+
return mocker.mock(member) { producer in
64+
let producer = try cast(producer) as () -> Int
65+
return producer()
66+
}
67+
}
68+
}
69+
enum Member: Matchable, CaseIdentifiable {
70+
case m1_foo
71+
case m2_bar(number: Parameter<Int>)
72+
func match(_ other: Member) -> Bool {
73+
switch (self, other) {
74+
case (.m1_foo, .m1_foo):
75+
return true
76+
case (.m2_bar(number: let leftNumber), .m2_bar(number: let rightNumber)):
77+
return leftNumber.match(rightNumber)
78+
default:
79+
return false
80+
}
81+
}
82+
}
83+
struct ReturnBuilder: EffectBuilder {
84+
private let mocker: Mocker<MockTest>
85+
init(mocker: Mocker<MockTest>) {
86+
self.mocker = mocker
87+
}
88+
var foo: FunctionReturnBuilder<MockTest, ReturnBuilder, Int, () -> Int> {
89+
.init(mocker, kind: .m1_foo)
90+
}
91+
func bar(number: Parameter<Int>) -> FunctionReturnBuilder<MockTest, ReturnBuilder, Int, (Int) -> Int> {
92+
.init(mocker, kind: .m2_bar(number: number))
93+
}
94+
}
95+
struct ActionBuilder: EffectBuilder {
96+
private let mocker: Mocker<MockTest>
97+
init(mocker: Mocker<MockTest>) {
98+
self.mocker = mocker
99+
}
100+
var foo: FunctionActionBuilder<MockTest, ActionBuilder> {
101+
.init(mocker, kind: .m1_foo)
102+
}
103+
func bar(number: Parameter<Int>) -> FunctionActionBuilder<MockTest, ActionBuilder> {
104+
.init(mocker, kind: .m2_bar(number: number))
105+
}
106+
}
107+
struct VerifyBuilder: AssertionBuilder {
108+
private let mocker: Mocker<MockTest>
109+
private let assertion: MockableAssertion
110+
init(mocker: Mocker<MockTest>, assertion: @escaping MockableAssertion) {
111+
self.mocker = mocker
112+
self.assertion = assertion
113+
}
114+
var foo: FunctionVerifyBuilder<MockTest, VerifyBuilder> {
115+
.init(mocker, kind: .m1_foo, assertion: assertion)
116+
}
117+
func bar(number: Parameter<Int>) -> FunctionVerifyBuilder<MockTest, VerifyBuilder> {
118+
.init(mocker, kind: .m2_bar(number: number), assertion: assertion)
119+
}
120+
}
121+
}
122+
#endif
123+
"""
124+
}
125+
}
126+
}

0 commit comments

Comments
 (0)
Please sign in to comment.