@@ -1045,6 +1045,62 @@ class TestJSONEncoder : XCTestCase {
1045
1045
XCTAssertEqual ( result. dict. count, 0 )
1046
1046
}
1047
1047
1048
+ func test_decodingWithSuperclassSpecialization( ) throws {
1049
+ class Animal : Codable {
1050
+ let name : String
1051
+ init ( name: String ) {
1052
+ self . name = name
1053
+ }
1054
+ }
1055
+ class Cat : Animal {
1056
+ let isDomestic : Bool
1057
+ private enum CodingKeys : String , CodingKey {
1058
+ case isDomestic
1059
+ }
1060
+ init ( name: String , isDomestic: Bool ) {
1061
+ self . isDomestic = isDomestic
1062
+ super. init ( name: name)
1063
+ }
1064
+ required init ( from decoder: Decoder ) throws {
1065
+ let container = try decoder. container ( keyedBy: CodingKeys . self)
1066
+ isDomestic = try container. decode ( Bool . self, forKey: . isDomestic)
1067
+ try super. init ( from: container. superDecoder ( ) )
1068
+ }
1069
+ override func encode( to encoder: Encoder ) throws {
1070
+ var container = encoder. container ( keyedBy: CodingKeys . self)
1071
+ try container. encode ( isDomestic, forKey: . isDomestic)
1072
+ try super. encode ( to: container. superEncoder ( ) )
1073
+ }
1074
+ }
1075
+
1076
+ let myCat = Cat ( name: " Maru " , isDomestic: true )
1077
+ let myPet : Animal = myCat
1078
+ let petData : Data
1079
+ do {
1080
+ petData = try JSONEncoder ( ) . encode ( myPet)
1081
+ }
1082
+ catch {
1083
+ XCTFail ( " Failed to encode the object: \( error) " )
1084
+ return
1085
+ }
1086
+
1087
+ let decodedPet : Animal
1088
+ do {
1089
+ decodedPet = try JSONDecoder ( ) . decode ( type ( of: myPet) , from: petData)
1090
+ }
1091
+ catch {
1092
+ XCTFail ( " Failed to decode the object: \( error) " )
1093
+ return
1094
+ }
1095
+
1096
+ guard let decodedCat = decodedPet as? Cat else {
1097
+ XCTFail ( " The decoded animal is not a cat " )
1098
+ return
1099
+ }
1100
+ XCTAssertEqual ( decodedCat. isDomestic, myCat. isDomestic)
1101
+ XCTAssertEqual ( decodedCat. name, myCat. name)
1102
+ }
1103
+
1048
1104
// MARK: - Helper Functions
1049
1105
private var _jsonEmptyDictionary : Data {
1050
1106
return " {} " . data ( using: . utf8) !
@@ -1651,6 +1707,7 @@ extension TestJSONEncoder {
1651
1707
( " test_dictionary_snake_case_encoding " , test_dictionary_snake_case_encoding) ,
1652
1708
( " test_OutputFormattingValues " , test_OutputFormattingValues) ,
1653
1709
( " test_SR17581_codingEmptyDictionaryWithNonstringKeyDoesRoundtrip " , test_SR17581_codingEmptyDictionaryWithNonstringKeyDoesRoundtrip) ,
1710
+ ( " test_decodingWithSuperclassSpecialization " , test_decodingWithSuperclassSpecialization) ,
1654
1711
]
1655
1712
}
1656
1713
}
0 commit comments