@@ -999,6 +999,62 @@ class TestJSONEncoder : XCTestCase {
999
999
XCTAssertEqual ( result. dict. count, 0 )
1000
1000
}
1001
1001
1002
+ func test_decodingWithSuperclassSpecialization( ) throws {
1003
+ class Animal : Codable {
1004
+ let name : String
1005
+ init ( name: String ) {
1006
+ self . name = name
1007
+ }
1008
+ }
1009
+ class Cat : Animal {
1010
+ let isDomestic : Bool
1011
+ private enum CodingKeys : String , CodingKey {
1012
+ case isDomestic
1013
+ }
1014
+ init ( name: String , isDomestic: Bool ) {
1015
+ self . isDomestic = isDomestic
1016
+ super. init ( name: name)
1017
+ }
1018
+ required init ( from decoder: Decoder ) throws {
1019
+ let container = try decoder. container ( keyedBy: CodingKeys . self)
1020
+ isDomestic = try container. decode ( Bool . self, forKey: . isDomestic)
1021
+ try super. init ( from: container. superDecoder ( ) )
1022
+ }
1023
+ override func encode( to encoder: Encoder ) throws {
1024
+ var container = encoder. container ( keyedBy: CodingKeys . self)
1025
+ try container. encode ( isDomestic, forKey: . isDomestic)
1026
+ try super. encode ( to: container. superEncoder ( ) )
1027
+ }
1028
+ }
1029
+
1030
+ let myCat = Cat ( name: " Maru " , isDomestic: true )
1031
+ let myPet : Animal = myCat
1032
+ let petData : Data
1033
+ do {
1034
+ petData = try JSONEncoder ( ) . encode ( myPet)
1035
+ }
1036
+ catch {
1037
+ XCTFail ( " Failed to encode the object: \( error) " )
1038
+ return
1039
+ }
1040
+
1041
+ let decodedPet : Animal
1042
+ do {
1043
+ decodedPet = try JSONDecoder ( ) . decode ( type ( of: myPet) , from: petData)
1044
+ }
1045
+ catch {
1046
+ XCTFail ( " Failed to decode the object: \( error) " )
1047
+ return
1048
+ }
1049
+
1050
+ guard let decodedCat = decodedPet as? Cat else {
1051
+ XCTFail ( " The decoded animal is not a cat " )
1052
+ return
1053
+ }
1054
+ XCTAssertEqual ( decodedCat. isDomestic, myCat. isDomestic)
1055
+ XCTAssertEqual ( decodedCat. name, myCat. name)
1056
+ }
1057
+
1002
1058
// MARK: - Helper Functions
1003
1059
private var _jsonEmptyDictionary : Data {
1004
1060
return " {} " . data ( using: . utf8) !
@@ -1605,6 +1661,7 @@ extension TestJSONEncoder {
1605
1661
( " test_dictionary_snake_case_encoding " , test_dictionary_snake_case_encoding) ,
1606
1662
( " test_OutputFormattingValues " , test_OutputFormattingValues) ,
1607
1663
( " test_SR17581_codingEmptyDictionaryWithNonstringKeyDoesRoundtrip " , test_SR17581_codingEmptyDictionaryWithNonstringKeyDoesRoundtrip) ,
1664
+ ( " test_decodingWithSuperclassSpecialization " , test_decodingWithSuperclassSpecialization) ,
1608
1665
]
1609
1666
}
1610
1667
}
0 commit comments