@@ -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
@@ -295,7 +312,7 @@ class TestJSONEncoder : TestJSONEncoderSuper {
295
312
encoder. nonConformingFloatEncodingStrategy = nonConformingFloatEncodingStrategy
296
313
payload = try encoder. encode ( value)
297
314
} catch {
298
- expectUnreachable ( " Failed to encode \( T . self) to JSON. " )
315
+ expectUnreachable ( " Failed to encode \( T . self) to JSON: \( error ) " )
299
316
}
300
317
301
318
if let expectedJSON = json {
@@ -310,7 +327,7 @@ class TestJSONEncoder : TestJSONEncoderSuper {
310
327
let decoded = try decoder. decode ( T . self, from: payload)
311
328
expectEqual ( decoded, value, " \( T . self) did not round-trip to an equal value. " )
312
329
} catch {
313
- expectUnreachable ( " Failed to decode \( T . self) from JSON. " )
330
+ expectUnreachable ( " Failed to decode \( T . self) from JSON: \( error ) " )
314
331
}
315
332
}
316
333
}
@@ -398,7 +415,7 @@ fileprivate enum Switch : Codable {
398
415
}
399
416
400
417
/// A simple timestamp type that encodes as a single Double value.
401
- fileprivate struct Timestamp : Codable {
418
+ fileprivate struct Timestamp : Codable , Equatable {
402
419
let value : Double
403
420
404
421
init ( _ value: Double ) {
@@ -414,10 +431,14 @@ fileprivate struct Timestamp : Codable {
414
431
var container = encoder. singleValueContainer ( )
415
432
try container. encode ( self . value)
416
433
}
434
+
435
+ static func == ( _ lhs: Timestamp , _ rhs: Timestamp ) -> Bool {
436
+ return lhs. value == rhs. value
437
+ }
417
438
}
418
439
419
440
/// A simple referential counter type that encodes as a single Int value.
420
- fileprivate final class Counter : Codable {
441
+ fileprivate final class Counter : Codable , Equatable {
421
442
var count : Int = 0
422
443
423
444
init ( ) { }
@@ -431,6 +452,10 @@ fileprivate final class Counter : Codable {
431
452
var container = encoder. singleValueContainer ( )
432
453
try container. encode ( self . count)
433
454
}
455
+
456
+ static func == ( _ lhs: Counter , _ rhs: Counter ) -> Bool {
457
+ return lhs === rhs || lhs. count == rhs. count
458
+ }
434
459
}
435
460
436
461
// MARK: - Structured Types
@@ -581,6 +606,62 @@ fileprivate struct DoubleNaNPlaceholder : Codable, Equatable {
581
606
}
582
607
}
583
608
609
+ /// A type which encodes as an array directly through a single value container.
610
+ struct Numbers : Codable , Equatable {
611
+ let values = [ 4 , 8 , 15 , 16 , 23 , 42 ]
612
+
613
+ init ( ) { }
614
+
615
+ init ( from decoder: Decoder ) throws {
616
+ let container = try decoder. singleValueContainer ( )
617
+ let decodedValues = try container. decode ( [ Int ] . self)
618
+ guard decodedValues == values else {
619
+ throw DecodingError . dataCorrupted ( DecodingError . Context ( codingPath: decoder. codingPath, debugDescription: " The Numbers are wrong! " ) )
620
+ }
621
+ }
622
+
623
+ func encode( to encoder: Encoder ) throws {
624
+ var container = encoder. singleValueContainer ( )
625
+ try container. encode ( values)
626
+ }
627
+
628
+ static func == ( _ lhs: Numbers , _ rhs: Numbers ) -> Bool {
629
+ return lhs. values == rhs. values
630
+ }
631
+
632
+ static var testValue : Numbers {
633
+ return Numbers ( )
634
+ }
635
+ }
636
+
637
+ /// A type which encodes as a dictionary directly through a single value container.
638
+ fileprivate final class Mapping : Codable , Equatable {
639
+ let values : [ String : URL ]
640
+
641
+ init ( values: [ String : URL ] ) {
642
+ self . values = values
643
+ }
644
+
645
+ init ( from decoder: Decoder ) throws {
646
+ let container = try decoder. singleValueContainer ( )
647
+ values = try container. decode ( [ String : URL ] . self)
648
+ }
649
+
650
+ func encode( to encoder: Encoder ) throws {
651
+ var container = encoder. singleValueContainer ( )
652
+ try container. encode ( values)
653
+ }
654
+
655
+ static func == ( _ lhs: Mapping , _ rhs: Mapping ) -> Bool {
656
+ return lhs === rhs || lhs. values == rhs. values
657
+ }
658
+
659
+ static var testValue : Mapping {
660
+ return Mapping ( values: [ " Apple " : URL ( string: " http://apple.com " ) !,
661
+ " localhost " : URL ( string: " http://127.0.0.1 " ) !] )
662
+ }
663
+ }
664
+
584
665
struct NestedContainersTestType : Encodable {
585
666
let testSuperEncoder : Bool
586
667
@@ -675,28 +756,29 @@ struct NestedContainersTestType : Encodable {
675
756
676
757
#if !FOUNDATION_XCTEST
677
758
var JSONEncoderTests = TestSuite ( " TestJSONEncoder " )
678
- JSONEncoderTests . test ( " testEncodingTopLevelEmptyStruct " ) { TestJSONEncoder ( ) . testEncodingTopLevelEmptyStruct ( ) }
679
- JSONEncoderTests . test ( " testEncodingTopLevelEmptyClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelEmptyClass ( ) }
680
- JSONEncoderTests . test ( " testEncodingTopLevelSingleValueEnum " ) { TestJSONEncoder ( ) . testEncodingTopLevelSingleValueEnum ( ) }
681
- JSONEncoderTests . test ( " testEncodingTopLevelSingleValueStruct " ) { TestJSONEncoder ( ) . testEncodingTopLevelSingleValueStruct ( ) }
682
- JSONEncoderTests . test ( " testEncodingTopLevelSingleValueClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelSingleValueClass ( ) }
683
- JSONEncoderTests . test ( " testEncodingTopLevelStructuredStruct " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredStruct ( ) }
684
- JSONEncoderTests . test ( " testEncodingTopLevelStructuredClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredClass ( ) }
685
- JSONEncoderTests . test ( " testEncodingTopLevelStructuredClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredClass ( ) }
759
+ JSONEncoderTests . test ( " testEncodingTopLevelEmptyStruct " ) { TestJSONEncoder ( ) . testEncodingTopLevelEmptyStruct ( ) }
760
+ JSONEncoderTests . test ( " testEncodingTopLevelEmptyClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelEmptyClass ( ) }
761
+ JSONEncoderTests . test ( " testEncodingTopLevelSingleValueEnum " ) { TestJSONEncoder ( ) . testEncodingTopLevelSingleValueEnum ( ) }
762
+ JSONEncoderTests . test ( " testEncodingTopLevelSingleValueStruct " ) { TestJSONEncoder ( ) . testEncodingTopLevelSingleValueStruct ( ) }
763
+ JSONEncoderTests . test ( " testEncodingTopLevelSingleValueClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelSingleValueClass ( ) }
764
+ JSONEncoderTests . test ( " testEncodingTopLevelStructuredStruct " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredStruct ( ) }
765
+ JSONEncoderTests . test ( " testEncodingTopLevelStructuredClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredClass ( ) }
766
+ JSONEncoderTests . test ( " testEncodingTopLevelStructuredSingleStruct " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredSingleStruct ( ) }
767
+ JSONEncoderTests . test ( " testEncodingTopLevelStructuredSingleClass " ) { TestJSONEncoder ( ) . testEncodingTopLevelStructuredSingleClass ( ) }
686
768
JSONEncoderTests . test ( " testEncodingTopLevelDeepStructuredType " ) { TestJSONEncoder ( ) . testEncodingTopLevelDeepStructuredType ( ) }
687
- JSONEncoderTests . test ( " testEncodingDate " ) { TestJSONEncoder ( ) . testEncodingDate ( ) }
688
- JSONEncoderTests . test ( " testEncodingDateSecondsSince1970 " ) { TestJSONEncoder ( ) . testEncodingDateSecondsSince1970 ( ) }
689
- JSONEncoderTests . test ( " testEncodingDateMillisecondsSince1970 " ) { TestJSONEncoder ( ) . testEncodingDateMillisecondsSince1970 ( ) }
690
- JSONEncoderTests . test ( " testEncodingDateISO8601 " ) { TestJSONEncoder ( ) . testEncodingDateISO8601 ( ) }
691
- JSONEncoderTests . test ( " testEncodingDateFormatted " ) { TestJSONEncoder ( ) . testEncodingDateFormatted ( ) }
692
- JSONEncoderTests . test ( " testEncodingDateCustom " ) { TestJSONEncoder ( ) . testEncodingDateCustom ( ) }
693
- JSONEncoderTests . test ( " testEncodingDateCustomEmpty " ) { TestJSONEncoder ( ) . testEncodingDateCustomEmpty ( ) }
694
- JSONEncoderTests . test ( " testEncodingBase64Data " ) { TestJSONEncoder ( ) . testEncodingBase64Data ( ) }
695
- JSONEncoderTests . test ( " testEncodingCustomData " ) { TestJSONEncoder ( ) . testEncodingCustomData ( ) }
696
- JSONEncoderTests . test ( " testEncodingCustomDataEmpty " ) { TestJSONEncoder ( ) . testEncodingCustomDataEmpty ( ) }
697
- JSONEncoderTests . test ( " testEncodingNonConformingFloats " ) { TestJSONEncoder ( ) . testEncodingNonConformingFloats ( ) }
698
- JSONEncoderTests . test ( " testEncodingNonConformingFloatStrings " ) { TestJSONEncoder ( ) . testEncodingNonConformingFloatStrings ( ) }
699
- JSONEncoderTests . test ( " testNestedContainerCodingPaths " ) { TestJSONEncoder ( ) . testNestedContainerCodingPaths ( ) }
700
- JSONEncoderTests . test ( " testSuperEncoderCodingPaths " ) { TestJSONEncoder ( ) . testSuperEncoderCodingPaths ( ) }
769
+ JSONEncoderTests . test ( " testEncodingDate " ) { TestJSONEncoder ( ) . testEncodingDate ( ) }
770
+ JSONEncoderTests . test ( " testEncodingDateSecondsSince1970 " ) { TestJSONEncoder ( ) . testEncodingDateSecondsSince1970 ( ) }
771
+ JSONEncoderTests . test ( " testEncodingDateMillisecondsSince1970 " ) { TestJSONEncoder ( ) . testEncodingDateMillisecondsSince1970 ( ) }
772
+ JSONEncoderTests . test ( " testEncodingDateISO8601 " ) { TestJSONEncoder ( ) . testEncodingDateISO8601 ( ) }
773
+ JSONEncoderTests . test ( " testEncodingDateFormatted " ) { TestJSONEncoder ( ) . testEncodingDateFormatted ( ) }
774
+ JSONEncoderTests . test ( " testEncodingDateCustom " ) { TestJSONEncoder ( ) . testEncodingDateCustom ( ) }
775
+ JSONEncoderTests . test ( " testEncodingDateCustomEmpty " ) { TestJSONEncoder ( ) . testEncodingDateCustomEmpty ( ) }
776
+ JSONEncoderTests . test ( " testEncodingBase64Data " ) { TestJSONEncoder ( ) . testEncodingBase64Data ( ) }
777
+ JSONEncoderTests . test ( " testEncodingCustomData " ) { TestJSONEncoder ( ) . testEncodingCustomData ( ) }
778
+ JSONEncoderTests . test ( " testEncodingCustomDataEmpty " ) { TestJSONEncoder ( ) . testEncodingCustomDataEmpty ( ) }
779
+ JSONEncoderTests . test ( " testEncodingNonConformingFloats " ) { TestJSONEncoder ( ) . testEncodingNonConformingFloats ( ) }
780
+ JSONEncoderTests . test ( " testEncodingNonConformingFloatStrings " ) { TestJSONEncoder ( ) . testEncodingNonConformingFloatStrings ( ) }
781
+ JSONEncoderTests . test ( " testNestedContainerCodingPaths " ) { TestJSONEncoder ( ) . testNestedContainerCodingPaths ( ) }
782
+ JSONEncoderTests . test ( " testSuperEncoderCodingPaths " ) { TestJSONEncoder ( ) . testSuperEncoderCodingPaths ( ) }
701
783
runAllTests ( )
702
784
#endif
0 commit comments