Skip to content

Commit

Permalink
.transcodeRawString now works with .useDefaultOnFailure
Browse files Browse the repository at this point in the history
  • Loading branch information
WendellXY committed Jul 22, 2024
1 parent 4b8cedf commit 96d76d3
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Sources/CodableKitMacros/CodableMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ extension CodableMacro {
patternName: key,
isOptional: property.isOptional,
useDefaultOnFailure: property.options.contains(.useDefaultOnFailure),
defaultValueExpr: nil,
defaultValueExpr: ExprSyntax(StringLiteralExprSyntax(content: "")),
type: TypeSyntax(IdentifierTypeSyntax(name: .identifier("String")))
)
)
Expand Down
230 changes: 199 additions & 31 deletions Tests/CodableKitTests/CodableMacroTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import XCTest

final class CodableKitTests: XCTestCase {
func testMacros() throws {
#if canImport(CodableKitMacros)
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
@Codable
Expand Down Expand Up @@ -55,13 +55,13 @@ final class CodableKitTests: XCTestCase {
macros: macros,
indentationWidth: .spaces(2)
)
#else
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
#endif
}

func testMacroWithDefaultValue() throws {
#if canImport(CodableKitMacros)
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
@Codable
Expand Down Expand Up @@ -103,13 +103,13 @@ final class CodableKitTests: XCTestCase {
macros: macros,
indentationWidth: .spaces(2)
)
#else
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
#endif
}

func testMacroWithCodableKeyAndDefaultValue() throws {
#if canImport(CodableKitMacros)
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
@Codable
Expand Down Expand Up @@ -152,13 +152,13 @@ final class CodableKitTests: XCTestCase {
macros: macros,
indentationWidth: .spaces(2)
)
#else
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
#endif
}

func testMacroWithOptionalValue() throws {
#if canImport(CodableKitMacros)
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
@Codable
Expand Down Expand Up @@ -200,13 +200,13 @@ final class CodableKitTests: XCTestCase {
macros: macros,
indentationWidth: .spaces(2)
)
#else
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
#endif
}

func testMacroWithIgnoredCodableKey() throws {
#if canImport(CodableKitMacros)
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
@Codable
Expand Down Expand Up @@ -251,13 +251,13 @@ final class CodableKitTests: XCTestCase {
macros: macros,
indentationWidth: .spaces(2)
)
#else
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
#endif
}

func testMacroWithExplicitNil() throws {
#if canImport(CodableKitMacros)
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
@Codable
Expand Down Expand Up @@ -305,13 +305,13 @@ final class CodableKitTests: XCTestCase {
macros: macros,
indentationWidth: .spaces(2)
)
#else
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
#endif
}

func testMacroWithOneCustomKeyGenerated() throws {
#if canImport(CodableKitMacros)
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
@Codable
Expand Down Expand Up @@ -358,13 +358,13 @@ final class CodableKitTests: XCTestCase {
macros: macros,
indentationWidth: .spaces(2)
)
#else
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
#endif
}

func testMacroWithTwoCustomKeyGenerated() throws {
#if canImport(CodableKitMacros)
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
@Codable
Expand Down Expand Up @@ -416,13 +416,13 @@ final class CodableKitTests: XCTestCase {
macros: macros,
indentationWidth: .spaces(2)
)
#else
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
#endif
}

func testMacroWithDecodingRawString() throws {
#if canImport(CodableKitMacros)
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
struct Room: Codable {
Expand Down Expand Up @@ -463,7 +463,7 @@ final class CodableKitTests: XCTestCase {
id = try container.decode(UUID.self, forKey: .id)
name = try container.decode(String.self, forKey: .name)
age = try container.decode(Int.self, forKey: .age)
let roomRawString = try container.decode(String.self, forKey: .room)
let roomRawString = try container.decodeIfPresent(String.self, forKey: .room) ?? ""
if let roomRawData = roomRawString.data(using: .utf8) {
room = try JSONDecoder().decode(Room.self, from: roomRawData)
} else {
Expand Down Expand Up @@ -500,13 +500,181 @@ final class CodableKitTests: XCTestCase {
macros: macros,
indentationWidth: .spaces(2)
)
#else
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
#endif
}

func testMacroWithDecodingRawStringAndIgnoreError() throws {
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
struct Room: Codable {
let id: UUID
let name: String
}
@Codable
public struct User {
let id: UUID
let name: String
let age: Int
@CodableKey(options: [.useDefaultOnFailure, .transcodeRawString])
let room: Room
}
""",
expandedSource: """
struct Room: Codable {
let id: UUID
let name: String
}
public struct User {
let id: UUID
let name: String
let age: Int
let room: Room
}
extension User: Codable {
enum CodingKeys: String, CodingKey {
case id
case name
case age
case room
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(UUID.self, forKey: .id)
name = try container.decode(String.self, forKey: .name)
age = try container.decode(Int.self, forKey: .age)
let roomRawString = (try? container.decodeIfPresent(String.self, forKey: .room)) ?? ""
if let roomRawData = roomRawString.data(using: .utf8) {
room = try JSONDecoder().decode(Room.self, from: roomRawData)
} else {
throw DecodingError.valueNotFound(
String.self,
DecodingError.Context(
codingPath: [CodingKeys.room],
debugDescription: "Failed to convert raw string to data"
)
)
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
try container.encode(age, forKey: .age)
let roomRawData = try JSONEncoder().encode(room)
if let roomRawString = String(data: roomRawData, encoding: .utf8) {
try container.encode(roomRawString, forKey: .room)
} else {
throw EncodingError.invalidValue(
roomRawData,
EncodingError.Context(
codingPath: [CodingKeys.room],
debugDescription: "Failed to transcode raw data to string"
)
)
}
}
}
""",
macros: macros,
indentationWidth: .spaces(2)
)
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
}

func testMacroWithDecodingRawStringWithDefaultValueAndIgnoreError() throws {
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
struct Room: Codable {
let id: UUID
let name: String
}
@Codable
public struct User {
let id: UUID
let name: String
let age: Int
@CodableKey(options: [.useDefaultOnFailure, .transcodeRawString])
var room: Room = Room(id: UUID(), name: "Hello")
}
""",
expandedSource: """
struct Room: Codable {
let id: UUID
let name: String
}
public struct User {
let id: UUID
let name: String
let age: Int
var room: Room = Room(id: UUID(), name: "Hello")
}
extension User: Codable {
enum CodingKeys: String, CodingKey {
case id
case name
case age
case room
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(UUID.self, forKey: .id)
name = try container.decode(String.self, forKey: .name)
age = try container.decode(Int.self, forKey: .age)
let roomRawString = (try? container.decodeIfPresent(String.self, forKey: .room)) ?? ""
if let roomRawData = roomRawString.data(using: .utf8) {
room = (try? JSONDecoder().decode(Room.self, from: roomRawData)) ?? Room(id: UUID(), name: "Hello")
} else {
throw DecodingError.valueNotFound(
String.self,
DecodingError.Context(
codingPath: [CodingKeys.room],
debugDescription: "Failed to convert raw string to data"
)
)
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
try container.encode(age, forKey: .age)
let roomRawData = try JSONEncoder().encode(room)
if let roomRawString = String(data: roomRawData, encoding: .utf8) {
try container.encode(roomRawString, forKey: .room)
} else {
throw EncodingError.invalidValue(
roomRawData,
EncodingError.Context(
codingPath: [CodingKeys.room],
debugDescription: "Failed to transcode raw data to string"
)
)
}
}
}
""",
macros: macros,
indentationWidth: .spaces(2)
)
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
}

func testMacrosWithOptionUseDefaultOnFailure() throws {
#if canImport(CodableKitMacros)
#if canImport(CodableKitMacros)
assertMacroExpansion(
"""
enum Role: UInt8, Codable {
Expand Down Expand Up @@ -564,8 +732,8 @@ final class CodableKitTests: XCTestCase {
macros: macros,
indentationWidth: .spaces(2)
)
#else
#else
throw XCTSkip("macros are only supported when running tests for the host platform")
#endif
#endif
}
}

0 comments on commit 96d76d3

Please sign in to comment.