-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added support for array of output objects. (#8)
* added support for array of output objects. * code review changes
- Loading branch information
1 parent
067b489
commit 9634ce3
Showing
9 changed files
with
284 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
@attached(peer, names: arbitrary) | ||
public macro Parametrize<T>(input: [T]) = #externalMacro(module: "XCTestParametrizedMacroMacros", type: "ParametrizeMacro") | ||
public macro Parametrize<I>(input: [I]) = #externalMacro(module: "XCTestParametrizedMacroMacros", type: "ParametrizeMacro") | ||
|
||
@attached(peer, names: arbitrary) | ||
public macro Parametrize<I, O>(input: [I], output: [O]) = #externalMacro(module: "XCTestParametrizedMacroMacros", type: "ParametrizeMacro") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,29 @@ | ||
import XCTestParametrizedMacro | ||
import XCTest | ||
|
||
enum Foo: Int { | ||
case first = 1 | ||
case second = 2 | ||
case third = 3 | ||
} | ||
|
||
func pow2(_ n: Int) -> Int { | ||
n*n | ||
} | ||
|
||
class Test { | ||
@Parametrize(input: [Foo.first, .second, .init(rawValue: 3)!]) | ||
func test_sample(input object: Foo) { | ||
print(object.rawValue) | ||
} | ||
|
||
@Parametrize(input: [1,2,3], output: [1,4,9]) | ||
func testPow2(input n: Int, output result: Int) { | ||
print("\(n) => \(result)") | ||
} | ||
|
||
@Parametrize(input: ["Swift","SwiftMacro"], output: [5, 10]) | ||
func testWordLength(input word: String, output length: Int) { | ||
XCTAssertEqual(word.count, length) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
Sources/XCTestParametrizedMacroMacros/TestMethodsFactory.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import Foundation | ||
import SwiftSyntax | ||
|
||
struct TestMethodsFactory { | ||
|
||
let macroDeclarationHelper: MacroDeclarationHelper | ||
|
||
var bodyFunc: String { | ||
get throws { | ||
guard let codeStatements = macroDeclarationHelper.funcStatements, codeStatements.count > 0 else { | ||
throw ParametrizeMacroError.functionBodyEmpty | ||
} | ||
return codeStatements.map { "\($0.trimmed)" }.joined(separator: "\n") | ||
} | ||
} | ||
|
||
func create() throws -> [DeclSyntax] { | ||
|
||
let funcName = macroDeclarationHelper.funcName | ||
|
||
guard let inputParamName = macroDeclarationHelper.inputParamName?.text else { | ||
throw ParametrizeMacroError.functionInputParamSecondNameMissing | ||
} | ||
|
||
guard let inputParamType = macroDeclarationHelper.inputParamType else { | ||
throw ParametrizeMacroError.functionInputParamTypeMissing | ||
} | ||
|
||
let outputParamName = macroDeclarationHelper.outputParamName?.text | ||
let outputParamType = macroDeclarationHelper.outputParamType | ||
|
||
let outputValues = try macroDeclarationHelper.outputValues | ||
let inputValues = try macroDeclarationHelper.inputValues | ||
if let outputValues = outputValues, | ||
let outputParamName = outputParamName, | ||
let outputParamType = outputParamType { | ||
let input = inputValues.map { $0 } | ||
let output = outputValues.map { $0 } | ||
guard input.count == output.count else { | ||
throw ParametrizeMacroError.macroAttributeArraysMismatchSize | ||
} | ||
return try zip(input, output).map { input, output in | ||
""" | ||
\(raw: buildTestMethodSignature(funcName: funcName, inputParamName: inputParamName, inputObject: input, outputParamName: outputParamName, outputObject: output)) | ||
\(raw: buildLocalVariables(inputParamName: inputParamName, | ||
inputParamType: inputParamType, | ||
inputObject: input, | ||
outputParamName: outputParamName, | ||
outputParamType: outputParamType, | ||
outputObject: output)) | ||
\(raw: try bodyFunc) | ||
} | ||
""" | ||
} | ||
} else { | ||
return try inputValues | ||
.map { | ||
""" | ||
\(raw: buildTestMethodSignature(funcName: funcName, inputParamName: inputParamName, inputObject: $0)) | ||
\(raw: buildLocalVariables(inputParamName: inputParamName, inputParamType: inputParamType, inputObject: $0)) | ||
\(raw: try bodyFunc) | ||
} | ||
""" | ||
} | ||
} | ||
} | ||
|
||
func buildTestMethodSignature(funcName: TokenSyntax, | ||
inputParamName: String, | ||
inputObject: ArrayElementListSyntax.Element, | ||
outputParamName: String? = nil, | ||
outputObject: ArrayElementListSyntax.Element? = nil) -> String { | ||
if let outputParamName = outputParamName, let outputObject = outputObject { | ||
return "func \(funcName)_\(inputParamName.capitalizedFirst)_\(inputObject.asFunctionName)_\(outputParamName.capitalizedFirst)_\(outputObject.asFunctionName)() throws {" | ||
} else { | ||
return "func \(funcName)_\(inputParamName.capitalizedFirst)_\(inputObject.asFunctionName)() throws {" | ||
} | ||
} | ||
|
||
func buildLocalVariables(inputParamName: String, | ||
inputParamType: TypeSyntax, | ||
inputObject: ArrayElementListSyntax.Element, | ||
outputParamName: String? = nil, | ||
outputParamType: TypeSyntax? = nil, | ||
outputObject: ArrayElementListSyntax.Element? = nil) -> String { | ||
var decl = "let \(inputParamName):\(inputParamType) = \(inputObject.expression)" | ||
if let outputParamName = outputParamName, | ||
let outputParamType = outputParamType, | ||
let outputObject = outputObject { | ||
decl.append("\n") | ||
decl.append("let \(outputParamName):\(outputParamType) = \(outputObject.expression)") | ||
} | ||
return decl | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
Tests/XCTestParametrizedMacroTests/InputOutputParametersTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import SwiftSyntaxMacros | ||
import SwiftSyntaxMacrosTestSupport | ||
import XCTest | ||
|
||
import XCTestParametrizedMacroMacros | ||
|
||
final class InputOutputParametersTests: XCTestCase { | ||
|
||
let testMacros: [String: Macro.Type] = [ | ||
"Parametrize": ParametrizeMacro.self, | ||
] | ||
|
||
func testParametrizeInputOutput_SingleInts() throws { | ||
assertMacroExpansion( | ||
""" | ||
struct TestStruct { | ||
@Parametrize(input: [3], output: [9]) | ||
func testPow2(input n: Int, output result: Int) { | ||
XCTAssertEqual(pow2(n),result) | ||
} | ||
} | ||
""", | ||
expandedSource: """ | ||
struct TestStruct { | ||
func testPow2(input n: Int, output result: Int) { | ||
XCTAssertEqual(pow2(n),result) | ||
} | ||
func testPow2_N_3_Result_9() throws { | ||
let n: Int = 3 | ||
let result: Int = 9 | ||
XCTAssertEqual(pow2(n), result) | ||
} | ||
} | ||
""", | ||
macros: testMacros | ||
) | ||
} | ||
|
||
func testParametrizeInputOutput_TwoInts() throws { | ||
assertMacroExpansion( | ||
""" | ||
struct TestStruct { | ||
@Parametrize(input: [4, 5], output: [16, 25]) | ||
func testPow2(input n: Int, output result: Int) { | ||
XCTAssertEqual(pow2(n),result) | ||
} | ||
} | ||
""", | ||
expandedSource: """ | ||
struct TestStruct { | ||
func testPow2(input n: Int, output result: Int) { | ||
XCTAssertEqual(pow2(n),result) | ||
} | ||
func testPow2_N_4_Result_16() throws { | ||
let n: Int = 4 | ||
let result: Int = 16 | ||
XCTAssertEqual(pow2(n), result) | ||
} | ||
func testPow2_N_5_Result_25() throws { | ||
let n: Int = 5 | ||
let result: Int = 25 | ||
XCTAssertEqual(pow2(n), result) | ||
} | ||
} | ||
""", | ||
macros: testMacros | ||
) | ||
} | ||
|
||
func testParametrizeInputOutput_TwoStringsTwoInts() throws { | ||
assertMacroExpansion( | ||
""" | ||
struct TestStruct { | ||
@Parametrize(input: ["Swift", "SwiftMacro"], output: [5, 10]) | ||
func testWordLength(input word: String, output length: Int) { | ||
XCTAssertEqual(word.count, length) | ||
} | ||
} | ||
""", | ||
expandedSource: """ | ||
struct TestStruct { | ||
func testWordLength(input word: String, output length: Int) { | ||
XCTAssertEqual(word.count, length) | ||
} | ||
func testWordLength_Word_Swift_Length_5() throws { | ||
let word: String = "Swift" | ||
let length: Int = 5 | ||
XCTAssertEqual(word.count, length) | ||
} | ||
func testWordLength_Word_SwiftMacro_Length_10() throws { | ||
let word: String = "SwiftMacro" | ||
let length: Int = 10 | ||
XCTAssertEqual(word.count, length) | ||
} | ||
} | ||
""", | ||
macros: testMacros | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -270,4 +270,5 @@ final class SimpleValuesTests: XCTestCase { | |
macros: testMacros | ||
) | ||
} | ||
|
||
} |