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