Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Excluding private modifiers for mock members #49

Merged
merged 1 commit into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Sources/MockableMacro/Factory/BuilderFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extension BuilderFactory {
_ requirements: Requirements
) throws -> some DeclSyntaxProtocol {
StructDeclSyntax(
modifiers: requirements.syntax.modifiers,
modifiers: requirements.modifiers,
name: kind.name,
inheritanceClause: InheritanceClauseSyntax(inheritedTypes: inheritedTypes(kind)),
memberBlock: MemberBlockSyntax(members: try members(kind, requirements))
Expand All @@ -53,7 +53,7 @@ extension BuilderFactory {
MemberBlockItemSyntax(
decl: try variable.builder(
of: kind,
with: requirements.syntax.modifiers,
with: requirements.modifiers,
using: requirements.syntax.mockType
)
)
Expand All @@ -62,7 +62,7 @@ extension BuilderFactory {
MemberBlockItemSyntax(
decl: try function.builder(
of: kind,
with: requirements.syntax.modifiers,
with: requirements.modifiers,
using: requirements.syntax.mockType
)
)
Expand Down Expand Up @@ -101,7 +101,7 @@ extension BuilderFactory {
_ requirements: Requirements
) -> InitializerDeclSyntax {
InitializerDeclSyntax(
modifiers: requirements.syntax.modifiers,
modifiers: requirements.modifiers,
signature: initializerSignature(kind, requirements)
) {
InfixOperatorExprSyntax(
Expand Down
6 changes: 3 additions & 3 deletions Sources/MockableMacro/Factory/ConformanceFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extension ConformanceFactory {
try MemberBlockItemListSyntax {
for variable in requirements.variables {
MemberBlockItemSyntax(
decl: try variable.implement(with: requirements.syntax.modifiers.trimmed)
decl: try variable.implement(with: requirements.modifiers)
)
}
}
Expand All @@ -37,7 +37,7 @@ extension ConformanceFactory {
try MemberBlockItemListSyntax {
for function in requirements.functions {
MemberBlockItemSyntax(
decl: try function.implement(with: requirements.syntax.modifiers.trimmed)
decl: try function.implement(with: requirements.modifiers)
)
}
}
Expand All @@ -47,7 +47,7 @@ extension ConformanceFactory {
try MemberBlockItemListSyntax {
for initializer in requirements.initializers {
MemberBlockItemSyntax(
decl: try initializer.implement(with: requirements.syntax.modifiers.trimmed)
decl: try initializer.implement(with: requirements.modifiers)
)
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/MockableMacro/Factory/EnumFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import SwiftSyntax
enum EnumFactory: Factory {
static func build(from requirements: Requirements) throws -> EnumDeclSyntax {
EnumDeclSyntax(
modifiers: requirements.syntax.modifiers,
modifiers: requirements.modifiers,
name: NS.Member,
inheritanceClause: inheritanceClause,
memberBlock: MemberBlockSyntax(members: try members(requirements))
Expand Down Expand Up @@ -67,7 +67,7 @@ extension EnumFactory {
try matcherSwitch(requirements)
}
let decl = FunctionDeclSyntax(
modifiers: requirements.syntax.modifiers,
modifiers: requirements.modifiers,
name: NS.match,
signature: signature,
body: .init(statements: statement)
Expand Down
10 changes: 5 additions & 5 deletions Sources/MockableMacro/Factory/MemberFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ enum MemberFactory: Factory {
extension MemberFactory {
private static func defaultInit(_ requirements: Requirements) -> InitializerDeclSyntax {
InitializerDeclSyntax(
modifiers: requirements.syntax.modifiers.trimmed,
modifiers: requirements.modifiers,
signature: .init(parameterClause: defaultInitParameters),
body: .init { CodeBlockItemSyntax(item: .expr(mockerAssignmentWithPolicy)) }
)
Expand Down Expand Up @@ -64,7 +64,7 @@ extension MemberFactory {
private static func given(_ requirements: Requirements) -> FunctionDeclSyntax {
FunctionDeclSyntax(
attributes: unavailableAttribute(message: Messages.givenMessage),
modifiers: requirements.syntax.modifiers,
modifiers: requirements.modifiers,
name: NS.given,
signature: .init(
parameterClause: FunctionParameterClauseSyntax(parameters: []),
Expand All @@ -78,7 +78,7 @@ extension MemberFactory {
private static func when(_ requirements: Requirements) -> FunctionDeclSyntax {
FunctionDeclSyntax(
attributes: unavailableAttribute(message: Messages.whenMessage),
modifiers: requirements.syntax.modifiers,
modifiers: requirements.modifiers,
name: NS.when,
signature: .init(
parameterClause: FunctionParameterClauseSyntax(parameters: []),
Expand All @@ -92,7 +92,7 @@ extension MemberFactory {
private static func verify(_ requirements: Requirements) -> FunctionDeclSyntax {
FunctionDeclSyntax(
attributes: unavailableAttribute(message: Messages.verifyMessage),
modifiers: requirements.syntax.modifiers,
modifiers: requirements.modifiers,
name: NS.verify,
signature: .init(
parameterClause: FunctionParameterClauseSyntax(
Expand All @@ -110,7 +110,7 @@ extension MemberFactory {
}
private static func reset(_ requirements: Requirements) -> FunctionDeclSyntax {
FunctionDeclSyntax(
modifiers: requirements.syntax.modifiers,
modifiers: requirements.modifiers,
name: NS.reset,
signature: .init(
parameterClause: FunctionParameterClauseSyntax(
Expand Down
10 changes: 8 additions & 2 deletions Sources/MockableMacro/Requirements/Requirements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ struct Requirements {

// MARK: Properties

var syntax: ProtocolDeclSyntax
let syntax: ProtocolDeclSyntax
let modifiers: DeclModifierListSyntax
var functions = [FunctionRequirement]()
var variables = [VariableRequirement]()
var initializers = [InitializerRequirement]()
Expand All @@ -20,12 +21,17 @@ struct Requirements {

init(_ syntax: ProtocolDeclSyntax) throws {
self.syntax = syntax

let members = syntax.memberBlock.members

guard members.compactMap({ $0.decl.as(SubscriptDeclSyntax.self) }).isEmpty else {
throw MockableMacroError.subscriptsNotSupported
}
self.modifiers = syntax.modifiers.trimmed.filter { modifier in
guard case .keyword(let keyword) = modifier.name.tokenKind else {
return true
}
return keyword != .private
}

self.variables = try members
.compactMap { $0.decl.as(VariableDeclSyntax.self) }
Expand Down
126 changes: 126 additions & 0 deletions Tests/MockableMacroTests/AccessModifierTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//
// File.swift
//
//
// Created by Nayanda Haberty on 29/5/24.
//

import MacroTesting
import XCTest
import SwiftSyntax
@testable import Mockable

final class AccessModifierTests: MockableMacroTestCase {
func test_private_access_modifier() {
assertMacro {
"""
@Mockable
private protocol Test {
var foo: Int { get }
func bar(number: Int) -> Int
}
"""
} expansion: {
"""
private protocol Test {
var foo: Int { get }
func bar(number: Int) -> Int
}

#if MOCKING
private final class MockTest: Test, MockableService {
private var mocker = Mocker<MockTest>()
@available(*, deprecated, message: "Use given(_ service:) of Mockable instead. ")
func given() -> ReturnBuilder {
.init(mocker: mocker)
}
@available(*, deprecated, message: "Use when(_ service:) of Mockable instead. ")
func when() -> ActionBuilder {
.init(mocker: mocker)
}
@available(*, deprecated, message: "Use verify(_ service:) of MockableTest instead. ")
func verify(with assertion: @escaping MockableAssertion) -> VerifyBuilder {
.init(mocker: mocker, assertion: assertion)
}
func reset(_ scopes: Set<MockerScope> = .all) {
mocker.reset(scopes: scopes)
}
init(policy: MockerPolicy? = nil) {
if let policy {
mocker.policy = policy
}
}
func bar(number: Int) -> Int {
let member: Member = .m2_bar(number: .value(number))
return mocker.mock(member) { producer in
let producer = try cast(producer) as (Int) -> Int
return producer(number)
}
}
var foo: Int {
get {
let member: Member = .m1_foo
return mocker.mock(member) { producer in
let producer = try cast(producer) as () -> Int
return producer()
}
}
}
enum Member: Matchable, CaseIdentifiable {
case m1_foo
case m2_bar(number: Parameter<Int>)
func match(_ other: Member) -> Bool {
switch (self, other) {
case (.m1_foo, .m1_foo):
return true
case (.m2_bar(number: let leftNumber), .m2_bar(number: let rightNumber)):
return leftNumber.match(rightNumber)
default:
return false
}
}
}
struct ReturnBuilder: EffectBuilder {
private let mocker: Mocker<MockTest>
init(mocker: Mocker<MockTest>) {
self.mocker = mocker
}
var foo: FunctionReturnBuilder<MockTest, ReturnBuilder, Int, () -> Int> {
.init(mocker, kind: .m1_foo)
}
func bar(number: Parameter<Int>) -> FunctionReturnBuilder<MockTest, ReturnBuilder, Int, (Int) -> Int> {
.init(mocker, kind: .m2_bar(number: number))
}
}
struct ActionBuilder: EffectBuilder {
private let mocker: Mocker<MockTest>
init(mocker: Mocker<MockTest>) {
self.mocker = mocker
}
var foo: FunctionActionBuilder<MockTest, ActionBuilder> {
.init(mocker, kind: .m1_foo)
}
func bar(number: Parameter<Int>) -> FunctionActionBuilder<MockTest, ActionBuilder> {
.init(mocker, kind: .m2_bar(number: number))
}
}
struct VerifyBuilder: AssertionBuilder {
private let mocker: Mocker<MockTest>
private let assertion: MockableAssertion
init(mocker: Mocker<MockTest>, assertion: @escaping MockableAssertion) {
self.mocker = mocker
self.assertion = assertion
}
var foo: FunctionVerifyBuilder<MockTest, VerifyBuilder> {
.init(mocker, kind: .m1_foo, assertion: assertion)
}
func bar(number: Parameter<Int>) -> FunctionVerifyBuilder<MockTest, VerifyBuilder> {
.init(mocker, kind: .m2_bar(number: number), assertion: assertion)
}
}
}
#endif
"""
}
}
}
2 changes: 1 addition & 1 deletion Tests/MockableTests/PolicyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extension Car: Mockable {
}

@Mockable
protocol PolicyService {
private protocol PolicyService {
func throwingVoidFunc() throws
var throwingVoidProp: Void { get throws }
func nonThrowingVoidFunc()
Expand Down
Loading