@@ -102,7 +102,103 @@ class TestJSONEncoder : TestJSONEncoderSuper {
102
102
_testRoundTrip ( of: TopLevelWrapper ( EnhancedBool . false) , expectedJSON: " { \" value \" :false} " . data ( using: . utf8) !)
103
103
_testRoundTrip ( of: TopLevelWrapper ( EnhancedBool . fileNotFound) , expectedJSON: " { \" value \" :null} " . data ( using: . utf8) !)
104
104
}
105
+
106
+ func testEncodingMultipleNestedContainersWithTheSameTopLevelKey( ) {
107
+ struct Model : Codable , Equatable {
108
+ let first : String
109
+ let second : String
110
+
111
+ init ( from coder: Decoder ) throws {
112
+ let container = try coder. container ( keyedBy: TopLevelCodingKeys . self)
113
+
114
+ let firstNestedContainer = try container. nestedContainer ( keyedBy: FirstNestedCodingKeys . self, forKey: . top)
115
+ self . first = try firstNestedContainer. decode ( String . self, forKey: . first)
116
+
117
+ let secondNestedContainer = try container. nestedContainer ( keyedBy: SecondNestedCodingKeys . self, forKey: . top)
118
+ self . second = try secondNestedContainer. decode ( String . self, forKey: . second)
119
+ }
120
+
121
+ func encode( to encoder: Encoder ) throws {
122
+ var container = encoder. container ( keyedBy: TopLevelCodingKeys . self)
123
+
124
+ var firstNestedContainer = container. nestedContainer ( keyedBy: FirstNestedCodingKeys . self, forKey: . top)
125
+ try firstNestedContainer. encode ( self . first, forKey: . first)
126
+
127
+ var secondNestedContainer = container. nestedContainer ( keyedBy: SecondNestedCodingKeys . self, forKey: . top)
128
+ try secondNestedContainer. encode ( self . second, forKey: . second)
129
+ }
130
+
131
+ init ( first: String , second: String ) {
132
+ self . first = first
133
+ self . second = second
134
+ }
135
+
136
+ static var testValue : Model {
137
+ return Model ( first: " Johnny Appleseed " ,
138
+
139
+ }
140
+
141
+ enum TopLevelCodingKeys : String , CodingKey {
142
+ case top
143
+ }
144
+
145
+ enum FirstNestedCodingKeys : String , CodingKey {
146
+ case first
147
+ }
148
+ enum SecondNestedCodingKeys : String , CodingKey {
149
+ case second
150
+ }
151
+ }
152
+
153
+ let model = Model . testValue
154
+ if #available( OSX 10 . 13 , iOS 11 . 0 , watchOS 4 . 0 , tvOS 11 . 0 , * ) {
155
+ let expectedJSON = " { \" top \" :{ \" first \" : \" Johnny Appleseed \" , \" second \" : \" [email protected] \" }} " . data ( using
: . utf8
) !
156
+ _testRoundTrip ( of: model, expectedJSON: expectedJSON, outputFormatting: [ . sortedKeys] )
157
+ } else {
158
+ _testRoundTrip ( of: model)
159
+ }
160
+ }
161
+
162
+ func testEncodingConflictedTypeNestedContainersWithTheSameTopLevelKey( ) {
163
+ struct Model : Encodable , Equatable {
164
+ let first : String
105
165
166
+ func encode( to encoder: Encoder ) throws {
167
+ var container = encoder. container ( keyedBy: TopLevelCodingKeys . self)
168
+
169
+ var firstNestedContainer = container. nestedContainer ( keyedBy: FirstNestedCodingKeys . self, forKey: . top)
170
+ try firstNestedContainer. encode ( self . first, forKey: . first)
171
+
172
+ // The following line would fail as it attempts to re-encode into already encoded container is invalid. This will always fail
173
+ var secondNestedContainer = container. nestedUnkeyedContainer ( forKey: . top)
174
+ try secondNestedContainer. encode ( " second " )
175
+ }
176
+
177
+ init ( first: String ) {
178
+ self . first = first
179
+ }
180
+
181
+ static var testValue : Model {
182
+ return Model ( first: " Johnny Appleseed " )
183
+ }
184
+
185
+ enum TopLevelCodingKeys : String , CodingKey {
186
+ case top
187
+ }
188
+ enum FirstNestedCodingKeys : String , CodingKey {
189
+ case first
190
+ }
191
+ }
192
+
193
+ let model = Model . testValue
194
+ // This following test would fail as it attempts to re-encode into already encoded container is invalid. This will always fail
195
+ if #available( OSX 10 . 13 , iOS 11 . 0 , watchOS 4 . 0 , tvOS 11 . 0 , * ) {
196
+ _testEncodeFailure ( of: model)
197
+ } else {
198
+ _testEncodeFailure ( of: model)
199
+ }
200
+ }
201
+
106
202
// MARK: - Output Formatting Tests
107
203
func testEncodingOutputFormattingDefault( ) {
108
204
let expectedJSON = " { \" name \" : \" Johnny Appleseed \" , \" email \" : \" [email protected] \" } " . data ( using
: . utf8
) !
@@ -1615,6 +1711,12 @@ JSONEncoderTests.test("testEncodingTopLevelStructuredSingleClass") { TestJSONEnc
1615
1711
JSONEncoderTests . test ( " testEncodingTopLevelDeepStructuredType " ) { TestJSONEncoder ( ) . testEncodingTopLevelDeepStructuredType ( ) }
1616
1712
JSONEncoderTests . test ( " testEncodingClassWhichSharesEncoderWithSuper " ) { TestJSONEncoder ( ) . testEncodingClassWhichSharesEncoderWithSuper ( ) }
1617
1713
JSONEncoderTests . test ( " testEncodingTopLevelNullableType " ) { TestJSONEncoder ( ) . testEncodingTopLevelNullableType ( ) }
1714
+ JSONEncoderTests . test ( " testEncodingMultipleNestedContainersWithTheSameTopLevelKey " ) { TestJSONEncoder ( ) . testEncodingMultipleNestedContainersWithTheSameTopLevelKey ( ) }
1715
+ JSONEncoderTests . test ( " testEncodingConflictedTypeNestedContainersWithTheSameTopLevelKey " ) {
1716
+ expectCrash ( ) {
1717
+ TestJSONEncoder ( ) . testEncodingConflictedTypeNestedContainersWithTheSameTopLevelKey ( )
1718
+ }
1719
+ }
1618
1720
JSONEncoderTests . test ( " testEncodingOutputFormattingDefault " ) { TestJSONEncoder ( ) . testEncodingOutputFormattingDefault ( ) }
1619
1721
JSONEncoderTests . test ( " testEncodingOutputFormattingPrettyPrinted " ) { TestJSONEncoder ( ) . testEncodingOutputFormattingPrettyPrinted ( ) }
1620
1722
JSONEncoderTests . test ( " testEncodingOutputFormattingSortedKeys " ) { TestJSONEncoder ( ) . testEncodingOutputFormattingSortedKeys ( ) }
0 commit comments