Skip to content

Commit 673c52c

Browse files
committed
fix bugs and add tests for test function name type
1 parent 031ae44 commit 673c52c

File tree

2 files changed

+95
-8
lines changed

2 files changed

+95
-8
lines changed

Sources/JSONAPISwiftGen/Swift Generators/Test Generators/TestFunctionName.swift

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public struct TestFunctionName: Equatable, RawRepresentable {
4545
/// To get the fully qualified name of the test, use `fullyQualifiedTestFunctionName`
4646
public var rawValue: String {
4747
return Self.testPrefix +
48-
fullyQualifiedTestFunctionName
48+
nameApplying(pathComponentTransform: Self.functionEncodedName)
4949
.replacingOccurrences(of: ".", with: "\(Self.periodReplacementCharacter)")
5050
}
5151

@@ -54,11 +54,29 @@ public struct TestFunctionName: Equatable, RawRepresentable {
5454
/// callable whereas the `rawValue` is the name of the test function
5555
/// that will call this callable.
5656
public var fullyQualifiedTestFunctionName: String {
57+
return nameApplying(pathComponentTransform: Self.swiftName)
58+
}
59+
60+
/// Will take a guess at what response status code is being tested, if applicable.
61+
/// The guess is determined using a known test name pattern of the status
62+
/// code being appending to the end of the test name after double underscores.
63+
public var testStatusCodeGuess: OpenAPI.Response.StatusCode? {
64+
let components = testName.components(separatedBy: "__")
65+
66+
guard components.count > 1 else { return nil }
67+
68+
return components.last.flatMap(OpenAPI.Response.StatusCode.init(rawValue:))
69+
}
70+
71+
/// This function facilitates a split between the `rawValue` and `fullyQualifiedTestFunctionName`
72+
/// because the former retains all path information with its `pathComponentTransform` whereas the
73+
/// latter is lossy with respect to some path component transformations.
74+
internal func nameApplying(pathComponentTransform: (String) -> String) -> String {
5775
let components = path.components
58-
+ [endpoint.rawValue, direction.rawValue]
76+
+ [endpoint.rawValue, direction.rawValue.capitalized]
5977

6078
return components
61-
.map(Self.swiftTypeName)
79+
.map(pathComponentTransform)
6280
.joined(separator: ".")
6381
+ ".\(testName)"
6482
}
@@ -76,9 +94,9 @@ public struct TestFunctionName: Equatable, RawRepresentable {
7694
return nil
7795
}
7896

79-
self.testName = String(components.removeLast())
97+
self.testName = Self.functionDecodedName(from: String(components.removeLast()))
8098

81-
guard let direction = HttpDirection(rawValue: String(components.removeLast())) else {
99+
guard let direction = HttpDirection(rawValue: String(components.removeLast()).lowercased()) else {
82100
return nil
83101
}
84102

@@ -90,7 +108,7 @@ public struct TestFunctionName: Equatable, RawRepresentable {
90108

91109
self.endpoint = endpoint
92110

93-
self.path = OpenAPI.Path(components.map(String.init))
111+
self.path = OpenAPI.Path(components.map(String.init).map(Self.functionDecodedName))
94112
}
95113

96114
public init(
@@ -105,14 +123,31 @@ public struct TestFunctionName: Equatable, RawRepresentable {
105123
self.testName = testName
106124
}
107125

108-
internal static func swiftTypeName(from string: String) -> String {
126+
/// For function name encoding we hold onto information like where there are
127+
/// spaces or braces.
128+
internal static func functionEncodedName(from string: String) -> String {
109129
return string
110130
.replacingOccurrences(of: "{", with: "\(Self.openBraceReplacementCharacter)")
111131
.replacingOccurrences(of: "}", with: "\(Self.closeBraceReplacementCharacter)")
112132
.replacingOccurrences(of: " ", with: "\(Self.spaceReplacementCharacter)")
113133
}
114134

115-
private static var testPrefix = "test__"
135+
internal static func functionDecodedName(from string: String) -> String {
136+
return string
137+
.replacingOccurrences(of: "\(Self.openBraceReplacementCharacter)", with: "{")
138+
.replacingOccurrences(of: "\(Self.closeBraceReplacementCharacter)", with: "}")
139+
.replacingOccurrences(of: "\(Self.spaceReplacementCharacter)", with: " ")
140+
}
141+
142+
/// For swift names, we remove braces and convert spaces to underscores.
143+
internal static func swiftName(from string: String) -> String {
144+
return string
145+
.replacingOccurrences(of: "{", with: "")
146+
.replacingOccurrences(of: "}", with: "")
147+
.replacingOccurrences(of: " ", with: "_")
148+
}
149+
150+
public static var testPrefix = "test__"
116151
private static var openBraceReplacementCharacter: Character = ""
117152
private static var closeBraceReplacementCharacter: Character = ""
118153
private static var spaceReplacementCharacter: Character = ""

Tests/JSONAPISwiftGenTests/TestFunctionNameTests.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77

88
import JSONAPISwiftGen
9+
import OpenAPIKit
910
import XCTest
1011

1112
final class TestFunctionNameTests: XCTestCase {
@@ -72,6 +73,57 @@ final class TestFunctionNameTests: XCTestCase {
7273
testName: "hello_world"
7374
)
7475
)
76+
77+
assertReflexiveRawValue(
78+
TestFunctionName(
79+
path: .init(["hello_world", "v2"]),
80+
endpoint: .get,
81+
direction: .request,
82+
testName: "hello_world"
83+
)
84+
)
85+
}
86+
87+
func test_statusCodeExtraction() {
88+
let test1 = TestFunctionName(
89+
path: .init(["hello_world", "v2"]),
90+
endpoint: .get,
91+
direction: .request,
92+
testName: "hello_world"
93+
)
94+
XCTAssertNil(test1.testStatusCodeGuess)
95+
96+
let test2 = TestFunctionName(
97+
path: .init(["hello_world", "v2"]),
98+
endpoint: .get,
99+
direction: .request,
100+
testName: "hello_world__hi"
101+
)
102+
XCTAssertNil(test2.testStatusCodeGuess)
103+
104+
let test3 = TestFunctionName(
105+
path: .init(["hello_world", "v2"]),
106+
endpoint: .get,
107+
direction: .request,
108+
testName: "hello_world__404"
109+
)
110+
XCTAssertEqual(test3.testStatusCodeGuess, OpenAPI.Response.StatusCode.status(code: 404))
111+
112+
let test4 = TestFunctionName(
113+
path: .init(["hello_world", "v2"]),
114+
endpoint: .get,
115+
direction: .request,
116+
testName: "hello_world__3xx"
117+
)
118+
XCTAssertEqual(test4.testStatusCodeGuess, OpenAPI.Response.StatusCode.range(.redirect))
119+
120+
let test5 = TestFunctionName(
121+
path: .init(["hello_world", "v2"]),
122+
endpoint: .get,
123+
direction: .request,
124+
testName: "hello_world__default"
125+
)
126+
XCTAssertEqual(test5.testStatusCodeGuess, OpenAPI.Response.StatusCode.default)
75127
}
76128

77129
func assertReflexiveRawValue(_ testName: TestFunctionName, file: StaticString = #file, line: UInt = #line) {

0 commit comments

Comments
 (0)