1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import MacroExamplesImplementation
import SwiftSyntaxMacros
import SwiftSyntaxMacrosTestSupport
import XCTest
final class AddAsyncMacroTests: XCTestCase {
private let macros = ["AddAsync": AddAsyncMacro.self]
func testExpansionTransformsFunctionWithResultCompletionToAsyncThrows() {
assertMacroExpansion(
#"""
@AddAsync
func c(a: Int, for b: String, _ value: Double, completionBlock: @escaping (Result<String, Error>) -> Void) -> Void {
completionBlock(.success("a: \(a), b: \(b), value: \(value)"))
}
"""#,
expandedSource: #"""
func c(a: Int, for b: String, _ value: Double, completionBlock: @escaping (Result<String, Error>) -> Void) -> Void {
completionBlock(.success("a: \(a), b: \(b), value: \(value)"))
}
func c(a: Int, for b: String, _ value: Double) async throws -> String {
try await withCheckedThrowingContinuation { continuation in
c(a: a, for: b, value) { returnValue in
switch returnValue {
case .success(let value):
continuation.resume(returning: value)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
"""#,
macros: macros,
indentationWidth: .spaces(2)
)
}
func testExpansionTransformsFunctionWithBoolCompletionToAsync() {
assertMacroExpansion(
"""
@AddAsync
func d(a: Int, for b: String, _ value: Double, completionBlock: @escaping (Bool) -> Void) -> Void {
completionBlock(true)
}
""",
expandedSource: """
func d(a: Int, for b: String, _ value: Double, completionBlock: @escaping (Bool) -> Void) -> Void {
completionBlock(true)
}
func d(a: Int, for b: String, _ value: Double) async -> Bool {
await withCheckedContinuation { continuation in
d(a: a, for: b, value) { returnValue in
continuation.resume(returning: returnValue)
}
}
}
""",
macros: macros,
indentationWidth: .spaces(2)
)
}
func testExpansionOnStoredPropertyEmitsError() {
assertMacroExpansion(
"""
struct Test {
@AddAsync
var name: String
}
""",
expandedSource: """
struct Test {
var name: String
}
""",
diagnostics: [
DiagnosticSpec(
message: "@addAsync only works on functions",
line: 2,
column: 3,
severity: .error
)
],
macros: macros,
indentationWidth: .spaces(2)
)
}
func testExpansionOnAsyncFunctionEmitsError() {
assertMacroExpansion(
"""
struct Test {
@AddAsync
async func sayHello() {
}
}
""",
expandedSource: """
struct Test {
async func sayHello() {
}
}
""",
diagnostics: [
DiagnosticSpec(
message: "@addAsync requires an function that returns void",
line: 2,
column: 3,
severity: .error
)
],
macros: macros,
indentationWidth: .spaces(2)
)
}
}
|