@@ -39,14 +39,19 @@ class TestJSONEncoder : TestJSONEncoderSuper {
39
39
func testEncodingTopLevelSingleValueEnum( ) {
40
40
_testEncodeFailure ( of: Switch . off)
41
41
_testEncodeFailure ( of: Switch . on)
42
+
43
+ _testRoundTrip ( of: TopLevelWrapper ( Switch . off) )
44
+ _testRoundTrip ( of: TopLevelWrapper ( Switch . on) )
42
45
}
43
46
44
47
func testEncodingTopLevelSingleValueStruct( ) {
45
48
_testEncodeFailure ( of: Timestamp ( 3141592653 ) )
49
+ _testRoundTrip ( of: TopLevelWrapper ( Timestamp ( 3141592653 ) ) )
46
50
}
47
51
48
52
func testEncodingTopLevelSingleValueClass( ) {
49
53
_testEncodeFailure ( of: Counter ( ) )
54
+ _testRoundTrip ( of: TopLevelWrapper ( Counter ( ) ) )
50
55
}
51
56
52
57
// MARK: - Encoding Top-Level Structured Types
@@ -63,6 +68,18 @@ class TestJSONEncoder : TestJSONEncoderSuper {
63
68
_testRoundTrip ( of: person, expectedJSON: expectedJSON)
64
69
}
65
70
71
+ func testEncodingTopLevelStructuredSingleStruct( ) {
72
+ // Numbers is a struct which encodes as an array through a single value container.
73
+ let numbers = Numbers . testValue
74
+ _testRoundTrip ( of: numbers)
75
+ }
76
+
77
+ func testEncodingTopLevelStructuredSingleClass( ) {
78
+ // Mapping is a class which encodes as a dictionary through a single value container.
79
+ let mapping = Mapping . testValue
80
+ _testRoundTrip ( of: mapping)
81
+ }
82
+
66
83
func testEncodingTopLevelDeepStructuredType( ) {
67
84
// Company is a type with fields which are Codable themselves.
68
85
let company = Company . testValue
@@ -326,7 +343,7 @@ class TestJSONEncoder : TestJSONEncoderSuper {
326
343
encoder. nonConformingFloatEncodingStrategy = nonConformingFloatEncodingStrategy
327
344
payload = try encoder. encode ( value)
328
345
} catch {
329
- expectUnreachable ( " Failed to encode \( T . self) to JSON. " )
346
+ expectUnreachable ( " Failed to encode \( T . self) to JSON: \( error ) " )
330
347
}
331
348
332
349
if let expectedJSON = json {
@@ -341,7 +358,7 @@ class TestJSONEncoder : TestJSONEncoderSuper {
341
358
let decoded = try decoder. decode ( T . self, from: payload)
342
359
expectEqual ( decoded, value, " \( T . self) did not round-trip to an equal value. " )
343
360
} catch {
344
- expectUnreachable ( " Failed to decode \( T . self) from JSON. " )
361
+ expectUnreachable ( " Failed to decode \( T . self) from JSON: \( error ) " )
345
362
}
346
363
}
347
364
}
@@ -429,7 +446,7 @@ fileprivate enum Switch : Codable {
429
446
}
430
447
431
448
/// A simple timestamp type that encodes as a single Double value.
432
- fileprivate struct Timestamp : Codable {
449
+ fileprivate struct Timestamp : Codable , Equatable {
433
450
let value : Double
434
451
435
452
init ( _ value: Double ) {
@@ -445,10 +462,14 @@ fileprivate struct Timestamp : Codable {
445
462
var container = encoder. singleValueContainer ( )
446
463
try container. encode ( self . value)
447
464
}
465
+
466
+ static func == ( _ lhs: Timestamp , _ rhs: Timestamp ) -> Bool {
467
+ return lhs. value == rhs. value
468
+ }
448
469
}
449
470
450
471
/// A simple referential counter type that encodes as a single Int value.
451
- fileprivate final class Counter : Codable {
472
+ fileprivate final class Counter : Codable , Equatable {
452
473
var count : Int = 0
453
474
454
475
init ( ) { }
@@ -462,6 +483,10 @@ fileprivate final class Counter : Codable {
462
483
var container = encoder. singleValueContainer ( )
463
484
try container. encode ( self . count)
464
485
}
486
+
487
+ static func == ( _ lhs: Counter , _ rhs: Counter ) -> Bool {
488
+ return lhs === rhs || lhs. count == rhs. count
489
+ }
465
490
}
466
491
467
492
// MARK: - Structured Types
@@ -612,6 +637,62 @@ fileprivate struct DoubleNaNPlaceholder : Codable, Equatable {
612
637
}
613
638
}
614
639
640
+ /// A type which encodes as an array directly through a single value container.
641
+ struct Numbers : Codable , Equatable {
642
+ let values = [ 4 , 8 , 15 , 16 , 23 , 42 ]
643
+
644
+ init ( ) { }
645
+
646
+ init ( from decoder: Decoder ) throws {
647
+ let container = try decoder. singleValueContainer ( )
648
+ let decodedValues = try container. decode ( [ Int ] . self)
649
+ guard decodedValues == values else {
650
+ throw DecodingError . dataCorrupted ( DecodingError . Context ( codingPath: decoder. codingPath, debugDescription: " The Numbers are wrong! " ) )
651
+ }
652
+ }
653
+
654
+ func encode( to encoder: Encoder ) throws {
655
+ var container = encoder. singleValueContainer ( )
656
+ try container. encode ( values)
657
+ }
658
+
659
+ static func == ( _ lhs: Numbers , _ rhs: Numbers ) -> Bool {
660
+ return lhs. values == rhs. values
661
+ }
662
+
663
+ static var testValue : Numbers {
664
+ return Numbers ( )
665
+ }
666
+ }
667
+
668
+ /// A type which encodes as a dictionary directly through a single value container.
669
+ fileprivate final class Mapping : Codable , Equatable {
670
+ let values : [ String : URL ]
671
+
672
+ init ( values: [ String : URL ] ) {
673
+ self . values = values
674
+ }
675
+
676
+ init ( from decoder: Decoder ) throws {
677
+ let container = try decoder. singleValueContainer ( )
678
+ values = try container. decode ( [ String : URL ] . self)
679
+ }
680
+
681
+ func encode( to encoder: Encoder ) throws {
682
+ var container = encoder. singleValueContainer ( )
683
+ try container. encode ( values)
684
+ }
685
+
686
+ static func == ( _ lhs: Mapping , _ rhs: Mapping ) -> Bool {
687
+ return lhs === rhs || lhs. values == rhs. values
688
+ }
689
+
690
+ static var testValue : Mapping {
691
+ return Mapping ( values: [ " Apple " : URL ( string: " http://apple.com " ) !,
692
+ " localhost " : URL ( string: " http://127.0.0.1 " ) !] )
693
+ }
694
+ }
695
+
615
696
struct NestedContainersTestType : Encodable {
616
697
let testSuperEncoder : Bool
617
698
@@ -713,6 +794,9 @@ JSONEncoderTests.test("testEncodingTopLevelSingleValueStruct") { TestJSONEncoder
713
794
JSONEncoderTests . test ( " testEncodingTopLevelSingleValueClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelSingleValueClass ( ) }
714
795
JSONEncoderTests . test ( " testEncodingTopLevelStructuredStruct " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredStruct ( ) }
715
796
JSONEncoderTests . test ( " testEncodingTopLevelStructuredClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredClass ( ) }
797
+ JSONEncoderTests . test ( " testEncodingTopLevelStructuredSingleStruct " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredSingleStruct ( ) }
798
+ JSONEncoderTests . test ( " testEncodingTopLevelStructuredSingleClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredSingleClass ( ) }
799
+ JSONEncoderTests . test ( " testEncodingTopLevelDeepStructuredType " ) { TestJSONEncoder ( ) . testEncodingTopLevelDeepStructuredType ( ) }
716
800
JSONEncoderTests . test ( " testEncodingTopLevelStructuredClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredClass ( ) }
717
801
JSONEncoderTests . test ( " testEncodingTopLevelDeepStructuredType " ) { TestJSONEncoder ( ) . testEncodingTopLevelDeepStructuredType ( ) }
718
802
JSONEncoderTests . test ( " testEncodingOutputFormattingDefault " ) { TestJSONEncoder ( ) . testEncodingOutputFormattingDefault ( ) }
0 commit comments